Целое число без знака в Javascript - PullRequest
37 голосов
/ 15 декабря 2009

Я работаю над страницей, которая обрабатывает информацию об 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

Ответы [ 6 ]

78 голосов
/ 15 декабря 2009
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, т.е. без изменений.

9 голосов
/ 15 декабря 2009

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

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

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

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

9 голосов
/ 15 декабря 2009

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

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

6 голосов
/ 15 декабря 2009

Javascript не имеет целых чисел, все числа на самом деле двойные.

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

3 голосов
/ 14 сентября 2011

Вот две функции, которые преобразуют адреса 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) );
}
0 голосов
/ 15 декабря 2009

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

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

...