Как сделать побитовое И в JavaScript на переменные, которые длиннее 32 бит? - PullRequest
21 голосов
/ 03 сентября 2010

У меня есть 2 числа в javascript, которые я хочу бит и. Они оба 33-битные

в C #:

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

но в javascript:

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

4294967296 is ((long) 1) << 32 </p>

Насколько я понимаю, это связано с тем, что JavaScript выполняет преобразование значений в int32 при выполнении побитовых операций.

Как мне обойти это? Любые предложения о том, как заменить бит и набор других математических операций, чтобы биты не были потеряны?

Ответы [ 4 ]

13 голосов
/ 03 сентября 2010

Вот забавная функция для сколь угодно больших целых чисел:

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-битные битовые операции.

6 голосов
/ 03 сентября 2010

Вы можете разделить каждую переменную на 2 32-битных значения (например, старшее и младшее слово), а затем выполнить побитовую операцию для обеих пар.

Сценарий ниже работает как сценарий Windows .js. Вы можете заменить WScript.Echo () на alert () для 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));
2 голосов
/ 03 сентября 2010

В Javascript есть несколько библиотек BigInteger, но ни один из них не предлагает побитовую операцию, которая вам нужна в данный момент. Если вы мотивированы и действительно нуждаетесь в этих функциях, вы можете изменить одну из этих библиотек и добавить метод для этого. Они уже предлагают хорошую базу кода для работы с огромным количеством.

Вы можете найти список библиотеки BigInteger в Javascript в этом вопросе:

Огромная целочисленная библиотека JavaScript

1 голос
/ 08 декабря 2017

Самое простое побитовое И, которое работает до максимального числа 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)
}
...