Целое число без знака в Javascript
-
19-09-2019 - |
Вопрос
Я работаю над страницей, которая обрабатывает информацию об 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-битные адреса, поэтому вам придется использовать массив.Я предполагаю, что сломано что-то еще.
[РЕДАКТИРОВАТЬ] Создайте небольшую библиотеку, которая использует массив из двух целых чисел в качестве внутреннего типа данных.