2009-11-20 60 views
6

我需要在JavaScript中執行64位整數的循環左移。但是:如何在JavaScript中模擬64位(無符號)整數的按位旋轉?

  • JavaScript的數字是雙打
  • 的JavaScript將它們轉換爲32位有符號整數,當你開始與< <與>>和>>>和〜及所有位變換的商業。然後當你完成後它又回到了雙打。我認爲。
  • 我不想要標誌。我絕對不想要小數位。但我絕對需要64位。

那麼,我該如何執行一個64位值的按位左旋?

+0

你肯定知道你的Javascript將始終在64位平臺上運行? – Amber 2009-11-20 02:50:13

+1

p.s.任何告訴我不要在JavaScript中執行此操作的人都需要Downvotes。沒有幫助!而且我知道這不是JavaScript非常適合的任務。但無論如何我需要這樣做。 KTHXBAI。 – Jeff 2009-11-20 02:50:36

+0

不是我相信你,但是如果JavaScript把它存儲在一個double中,那麼它是一個double而不是一個64位int(不管符號是什麼)。 – 2009-11-20 02:51:07

回答

12

保持您的64位數作爲單獨的高低兩半。旋轉左移N當N < 32:

hi_rot = ((hi << N) | (lo >>> (32-N))) & (0xFFFFFFFF)

lo_rot = ((lo << N) | (hi >>> (32-N))) & (0xFFFFFFFF)

如果N> = 32,然後減去選自N 32,交換HI和LO,然後執行上述內容。

+0

我喜歡這樣做的方式,但數字簽署的事實會導致任何陷阱?最重要的位存儲標誌。 – Jeff 2009-11-20 05:47:43

+0

哦,你說小於32.看起來像是照顧這個問題。 – Jeff 2009-11-20 05:55:24

+1

唯一的問題是'&(0xFFFFFFFF)'在這裏是一個無操作。如果你想使數字無符號,請使用>>> 0代替。 – 2009-11-20 06:22:13

4

我相信如此,雖然不是最有效的方法,但將數字轉換爲二進制形式的字符串(64位),使用子字符串在開始時移動字符並將其附加到結尾(用於左旋轉)並將二進制形式轉換回數字。我相信你可以弄清楚如何將一個十進制數字轉換成二進制形式爲一個字符串並返回。

+0

我想我要求反對票嗎? :-) – Murali 2009-11-20 03:02:37

+0

+1:這是一個很奇怪的問題的解決方案。 – 2009-11-20 03:05:04

+2

不,這是一個合法的解決方案,即使它不是我希望的那種解決方案。沒有降低你的價值。 – Jeff 2009-11-20 03:08:41

0

我認爲可以做的唯一方法是創建一個int64類,它內部包含兩個32位整數,並通過在它們之間進行移位來進行移位。

0

這是一個基於數值的旋轉。

double d = 12345678901.0; 
// get high int bits in hi, and the low in 
int hi = (int)(d/16.0/16.0/16.0/16.0); 
int low = (int)d; 

int rot = 3; // thus * 8 
int newhi = (low >> (32 - rot)) | (hi << rot); 
int newlow = (hi >> (32 - rot)) | (low << rot); 

double newdouble = ((double)hi * 16.0 * 16.0 * 16.0 * 16.0) + (double)low; 
+0

那麼這是一個C#版本,並且由於signed int的最後一步實際上並不像預期的那樣工作。事實上,它最有可能也不會用於負雙打以太... ... – 2009-11-20 03:24:20

+0

使用原子操作非常慢,特別是當你想轉換大量的字節,例如,圖像數據,這不是一個實際的解決方案。 – 2016-09-30 10:08:00

1

由於@Doug柯里把它放在你需要代表64位數字作爲兩個數字,然後做對他們的逐位運算。我使用的代碼是:

//Constructor for a Long.. 
function Long(high, low) { 
    //note: doing "or 0", truncates to 32 bit signed 
    //big-endian 2's complement int.. 
    this._high = high | 0; 
    this._low = low | 0; 
} 
Long.prototype.rotateLeft = function(bits) { 
    var newHigh; 
    if(bits === 32){ //just switch high and low over in this case.. 
     newHigh = this._low; 
     this._low = this._high; 
     this._high = newHigh; 
    } else { 
     newHigh = (this._high << bits) | (this._low >>> (32-bits)); 
     this._low = (this._low << bits) | (this._high >>> (32-bits)); 
     this._high = newHigh; 
    } 
    return this; //for chaining.. 
}; 
//Rotates the bits of this word round to the right (max 32).. 
Long.prototype.rotateRight = function(bits) { 
    var newHigh; 
    if(bits === 32){ //just switch high and low over in this case.. 
     newHigh = this._low; 
     this._low = this._high; 
     this._high = newHigh; 
    } else { 
     newHigh = (this._low << (32-bits)) | (this._high >>> bits); 
     this._low = (this._high << (32-bits)) | (this._low >>> bits); 
     this._high = newHigh; 
    } 
    return this; //for chaining.. 
}; 

要使用它,嘗試運行:console.log(new Long(0,1).rotateLeft(4));然後檢查_high和_low性能。

0

我想試試這個:

function rotate(hi,lo,n) { 
    var N = n/%32; 
    if(Math.floor(n/32)%2) { 
     var hi_rot = ((hi << N) | (lo >>> (32-N))) & (~0); 
     var lo_rot = ((lo << N) | (hi >>> (32-N))) & (~0); 
    } else { 
     var hi_rot = ((lo << N) | (hi >>> (32-N))) & (~0); 
     var lo_rot = ((hi << N) | (lo >>> (32-N))) & (~0); 
    } 
    return (hi_rot<<32)+lo_rot; 
} 
相關問題