Подтвердить что ты не робот

Беззнаковое целое в Javascript

Я работаю над страницей, обрабатывающей информацию о IP-адресе, но она задыхается от того, что целые числа подписаны. Я использую побитовые операторы, чтобы ускорить его, но 64-й бит (подписанный/неподписанный флаг) испортил его.

Есть ли способ заставить число быть неподписанным в Javascript? Кажется, что он работает нормально, пока подсеть больше 30 или меньше 2.

Попробуйте следующее:

<html>
<body>

<script type='text/javascript'>
document.write( (1 << 30) +"<br/>");
document.write( (1 << 31) +"<br/>");
document.write( (1 << 32) +"<br/>");
</script>

</body>
</html>

Результат:

1073741824 -2147483648 1

4b9b3361

Ответ 1

document.write( (1 << 31) +"<br/>");

Оператор << определяется как работающий с подписанными 32-битными целыми числами (преобразованный из собственного хранилища чисел с плавающей точкой с двойной точностью). Поэтому 1<<31 должно приводить к отрицательному числу.

Единственный оператор JavaScript, который работает с 32-разрядными целыми числами без знака, равен >>>. Вы можете использовать это для преобразования подписанного целого числа в число, с которым вы работали с другими побитовыми операторами, в unsigned-integer-in-Number:

document.write(( (1<<31)>>>0 )+'<br />');

Тем:

document.write( (1 << 32) +"<br/>");

не будет работать, потому что все операции сдвига используют только самые младшие 5 бит сдвига (в JavaScript и других языках, подобных C). <<32 равно <<0, т.е. без изменений.

Ответ 2

Используйте → > вместо → , чтобы получить сдвиг без знака вместо знакового. Все остальные побитовые операторы ведут себя одинаково независимо от того, подписаны ли ints.

Нарушение кода "когда подсеть... меньше 2". Похоже, что у вас может быть некоторая ошибка, не связанная с подписью целых чисел.

Ответ 3

Javascript не имеет целых чисел, все числа фактически удваиваются.

Ссылка Javascript 1.5 от Mozilla предполагает, что можно безопасно использовать побитовые операции для 32-разрядных чисел.

Ответ 4

Дуглас Крокфорд считает, что побитовые операторы являются одной из плохих частей javascript:

В Java побитовые операторы работают с целыми числами. JavaScript не имеет целых чисел. Он имеет только числа с плавающей запятой двойной точности. Таким образом, побитовые операторы преобразуют свои операнды чисел в целые числа, выполняют свою деятельность и затем конвертируют их обратно. В большинстве языков эти операторы очень близки к аппаратным средствам и очень быстры. В JavaScript они очень далеки от аппаратного обеспечения и очень медленны. JavaScript редко используется для выполнения манипуляций с битами.

- Дуглас Крокфорд в "JavaScript: хорошие детали", Приложение B, Побитовые операторы (выделено мной)

Вы уверены, что побитовые операторы действительно ускоряют вашу логику?

Ответ 5

Вот две функции, которые преобразуют адреса ipv4 в/из целых без знака в javascript:

function ip2long(ip) {
    var ipl=0;
    ip.split('.').forEach(function( octet ) {
        ipl<<=8;
        ipl+=parseInt(octet);
    });
    return(ipl >>>0);
}

function long2ip (ipl) {
    return ( (ipl>>>24) +'.' +
        (ipl>>16 & 255) +'.' +
        (ipl>>8 & 255) +'.' +
        (ipl & 255) );
}

Ответ 6

Какие у вас IP-адреса? IPv4 использует только 32-битные адреса, поэтому JavaScript должен быть хорошим (с использованием double, который дает 52-битную целую часть). IPv6 использует 128-битные адреса, поэтому вам придется использовать массив. Я предполагаю, что что-то еще сломано.

[EDIT] Создайте небольшую библиотеку, которая использует в качестве внутреннего типа данных массив из двух ints.