如何在 javascript 中对超过 32 位的变量进行按位 AND 操作?

发布于 2024-09-17 23:14:37 字数 378 浏览 7 评论 0原文

我在 javascript 中有 2 个数字,我想对它进行位和。它们

在 C# 中都是 33 位长:

 ((4294967296 & 4294967296 )==0) is false

但在 javascript 中:

 ((4294967296 & 4294967296 )==0) is true

4294967296 是 ((long)1) << 32

据我了解,这是由于javascript在执行按位运算时将值转换为int32。

我该如何解决这个问题? 关于如何替换位以及使用一组其他数学运算以便不丢失位有什么建议吗?

I have 2 numbers in javascript that I want to bit and. They both are 33bit long

in C#:

 ((4294967296 & 4294967296 )==0) is false

but in javascript:

 ((4294967296 & 4294967296 )==0) is true

4294967296 is ((long)1) << 32

As I understand it, it is due to the fact that javascript converts values to int32 when performing bit wise operations.

How do I work around this?
Any suggestions on how to replace bit and with a set of other math operations so that bits are not lost?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

关于从前 2024-09-24 23:14:37

这是一个适用于任意大整数的有趣函数:

function BitwiseAndLarge(val1, val2) {
    var shift = 0, result = 0;
    var mask = ~((~0) << 30); // Gives us a bit mask like 01111..1 (30 ones)
    var divisor = 1 << 30; // To work with the bit mask, we need to clear bits at a time
    while( (val1 != 0) && (val2 != 0) ) {
        var rs = (mask & val1) & (mask & val2);
        val1 = Math.floor(val1 / divisor); // val1 >>> 30
        val2 = Math.floor(val2 / divisor); // val2 >>> 30
        for(var i = shift++; i--;) {
            rs *= divisor; // rs << 30
        }
        result += rs;
    }
    return result;
}

假设系统正确处理至少 30 位按位运算。

Here's a fun function for arbitrarily large integers:

function BitwiseAndLarge(val1, val2) {
    var shift = 0, result = 0;
    var mask = ~((~0) << 30); // Gives us a bit mask like 01111..1 (30 ones)
    var divisor = 1 << 30; // To work with the bit mask, we need to clear bits at a time
    while( (val1 != 0) && (val2 != 0) ) {
        var rs = (mask & val1) & (mask & val2);
        val1 = Math.floor(val1 / divisor); // val1 >>> 30
        val2 = Math.floor(val2 / divisor); // val2 >>> 30
        for(var i = shift++; i--;) {
            rs *= divisor; // rs << 30
        }
        result += rs;
    }
    return result;
}

Assuming that the system handles at least 30-bit bitwise operations properly.

那些过往 2024-09-24 23:14:37

您可以将每个变量拆分为 2 个 32 位值(如高位字和低位字),然后对两对进行按位运算。

下面的脚本作为 Windows .js 脚本运行。对于 Web,您可以将 WScript.Echo() 替换为alert()。

var a = 4294967296;
var b = 4294967296;

var w = 4294967296; // 2^32

var aHI = a / w;
var aLO = a % w;
var bHI = b / w;
var bLO = b % w;

WScript.Echo((aHI & bHI) * w + (aLO & bLO));

You could split each of the vars into 2 32-bit values (like a high word and low word), then do a bitwise operation on both pairs.

The script below runs as a Windows .js script. You can replace WScript.Echo() with alert() for Web.

var a = 4294967296;
var b = 4294967296;

var w = 4294967296; // 2^32

var aHI = a / w;
var aLO = a % w;
var bHI = b / w;
var bLO = b % w;

WScript.Echo((aHI & bHI) * w + (aLO & bLO));
笨死的猪 2024-09-24 23:14:37

Javascript 中有多个 BigInteger 库,但目前没有一个提供您需要的按位运算。如果您有动力并且确实需要该功能,您可以修改其中一个库并添加一种方法来执行此操作。他们已经提供了一个很好的代码库来处理大量的数据。

您可以在这个问题中找到 Javascript 中 BigInteger 库的列表:

巨大整数 JavaScript 库

There are several BigInteger librairy in Javascript, but none of them offer bitwise operation you need at the moment. If you are motivated and really need that functionality you can modify one of those librairy and add a method to do so. They already offer a good code base to work with huge number.

You can find a list of the BigInteger librairy in Javascript in this question :

Huge Integer JavaScript Library

思念满溢 2024-09-24 23:14:37

最简单的按位与,最多可达 JavaScript 的最大数字

由于内部原因,JavaScript 的最大整数值为 2^53(它是一个双精度浮点数)。如果您需要更多,可以使用一些很好的库来处理大整数。

2^53 是 9,007,199,254,740,992,或大约 9,000 万亿(约 9 万亿)。

// Works with values up to 2^53
function bitwiseAnd_53bit(value1, value2) {
    const maxInt32Bits = 4294967296; // 2^32

    const value1_highBits = value1 / maxInt32Bits;
    const value1_lowBits = value1 % maxInt32Bits;
    const value2_highBits = value2 / maxInt32Bits;
    const value2_lowBits = value2 % maxInt32Bits;
    return (value1_highBits & value2_highBits) * maxInt32Bits + (value1_lowBits & value2_lowBits)
}

The simplest bit-wise AND, that works up to JavaScript's maximum number

JavaScript's max integer value is 2^53 for internal reasons (it's a double float). If you need more there are good libraries for that big integer handling.

2^53 is 9,007,199,254,740,992, or about 9,000 trillion (~9 quadrillion).

// Works with values up to 2^53
function bitwiseAnd_53bit(value1, value2) {
    const maxInt32Bits = 4294967296; // 2^32

    const value1_highBits = value1 / maxInt32Bits;
    const value1_lowBits = value1 % maxInt32Bits;
    const value2_highBits = value2 / maxInt32Bits;
    const value2_lowBits = value2 % maxInt32Bits;
    return (value1_highBits & value2_highBits) * maxInt32Bits + (value1_lowBits & value2_lowBits)
}
别念他 2024-09-24 23:14:37

今天遇到这个问题,这就是我想到的:

function bitwiseAnd(firstNumber, secondNumber) {
    let // convert the numbers to binary strings
        firstBitArray = (firstNumber).toString(2),
        secondBitArray = (secondNumber).toString(2),
        resultedBitArray = [],
        // get the length of the largest number
        maxLength = Math.max(firstBitArray.length, secondBitArray.length);

        //add zero fill ahead in case the binary strings have different lengths
        //so we can have strings equal in length and compare bit by bit
        firstBitArray = firstBitArray.padStart(maxLength,'0');
        secondBitArray = secondBitArray.padStart(maxLength,'0');

        // bit by bit comparison
        for(let i = 0; i < maxLength; i++) {
            resultedBitArray.push(parseInt(firstBitArray[i]) && secondBitArray[i]);
        }

        //concat  the result array back to a string and parse the binary string back to an integer
        return parseInt(resultedBitArray.join(''),2);
}

希望这可以帮助遇到这个问题的其他人。

Ran into this problem today and this is what I came up with:

function bitwiseAnd(firstNumber, secondNumber) {
    let // convert the numbers to binary strings
        firstBitArray = (firstNumber).toString(2),
        secondBitArray = (secondNumber).toString(2),
        resultedBitArray = [],
        // get the length of the largest number
        maxLength = Math.max(firstBitArray.length, secondBitArray.length);

        //add zero fill ahead in case the binary strings have different lengths
        //so we can have strings equal in length and compare bit by bit
        firstBitArray = firstBitArray.padStart(maxLength,'0');
        secondBitArray = secondBitArray.padStart(maxLength,'0');

        // bit by bit comparison
        for(let i = 0; i < maxLength; i++) {
            resultedBitArray.push(parseInt(firstBitArray[i]) && secondBitArray[i]);
        }

        //concat  the result array back to a string and parse the binary string back to an integer
        return parseInt(resultedBitArray.join(''),2);
}

Hope this helps anyone else who runs into this problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文