Вопрос

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

Есть ли какой-нибудь способ заставить число быть неподписанным в 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

Это было полезно?

Решение

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

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

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

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

Тем временем:

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

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

Другие советы

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

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

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

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

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

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

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

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

Вот две функции, которые преобразуют 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) );
}

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

[РЕДАКТИРОВАТЬ] Создайте небольшую библиотеку, которая использует массив из двух целых чисел в качестве внутреннего типа данных.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top