如何在JavaScript中模拟64位(无符号)整数的按位旋转?

问题描述 投票:6回答:5

我需要在JavaScript中执行64位整数的循环左移。然而:

  • JavaScript数字是双打的
  • 当你开始使用<<和>>以及>>>和〜以及所有比特笨拙的业务时,JavaScript会将它们转换为32位有符号的整数。然后,当你完成时,它又回到了双打。我认为。
  • 我不想要这个标志。而且我绝对不希望小数位。但我绝对想要64位。

那么,如何执行64位值的按位左旋转?

javascript bit-manipulation
5个回答
12
投票

将64位数字保留为单独的高分区和低分区。当N <32时向左旋转N:

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

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

如果N> = 32,则从N中减去32,交换hi和lo,然后执行上述操作。


4
投票

我相信,虽然不是最有效的方法,但是将数字转换为二进制形式的字符串(64位),使用substring在开头移动char并将其追加到末尾(用于左旋转)并转换二进制形成回到数字。我相信你可以弄清楚如何将十进制数转换为二进制形式为字符串并返回。


1
投票

正如@Doug Currie所说,你需要将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
投票

我认为可以做的唯一方法是创建一个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;
© www.soinside.com 2019 - 2024. All rights reserved.