2009-11-20 92 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; 
} 
相关问题