无符号整数在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
document.write( (1 << 31) +"<br/>");
<<
运算符被定义为使用带符号的32位整数(从双精度浮点数的本地数字存储器转换而来)。 所以1<<31
必须导致一个负数。
使用无符号32位整数的唯一JavaScript运算符是>>>
。 你可以利用这个来将你已经使用的其他按位运算符的signed-integer-in-Number转换为一个unsigned-integer-in-Number:
document.write(( (1<<31)>>>0 )+'<br />');
与此同时:
document.write( (1 << 32) +"<br/>");
将不起作用,因为所有的移位操作只使用最低5位的移位(在JavaScript和其他类似C语言中)。 <<32
等于<<0
,即。 不用找了。
使用>>>而不是>>来获得一个无符号的右移,而不是一个符号扩展。 所有其他按位运算符的行为方式相同,无论ints是否有符号。
你的代码打破“当子网…小于2”是关于。 这听起来像你可能有一些与整数签名无关的bug。
JavaScript没有整数,所有的数字实际上是双打的。
Mozilla的Javascript 1.5参考文献指出,只能使用32位数字的安全位操作。
道格拉斯·克罗克福德(Douglas Crockford)认为,按位运算符是javascript的一个不好的部分:
在Java中,按位运算符使用整数。 JavaScript没有整数。 它只有双精度浮点数。 所以,按位运算符将其数字操作数转换为整数,做他们的业务,然后将其转换回来。 在大多数语言中,这些操作员非常接近硬件,速度非常快。 在JavaScript中,它们离硬件很远,速度很慢。 JavaScript很less用于位操作。
– 道格拉斯·克罗克福德在“JavaScript:好的部分”,附录B,按位运算符(强调增加)
你确定那些按位运算符真的能加快你的逻辑吗?
这里有两个函数将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应该没问题(使用双精度可以给你一个52bit的整数部分 )。 IPv6使用128位地址,所以你必须使用一个数组。 我的猜测是别的东西坏了。
[编辑]build立一个小型的库,使用一个两个整数的数组作为内部数据types。