JavaScript 中的无符号整数

发布于 2024-08-15 12:38:00 字数 632 浏览 9 评论 0原文

我正在开发一个处理 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

I'm working on a page that processes IP address information, but it's choking on the fact that integers are signed. I am using bitwise operators to speed it up, but the 64th bit (signed/unsigned flag) is messing it up.

Is there any way to force a number to be unsigned in Javascript? It seems to work fine, until subnet is greater than 30, or less than 2.

Try this:

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

Result:

1073741824
-2147483648
1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

梦旅人picnic 2024-08-22 12:38:00
document.write( (1 << 31) +"<br/>");

<< 运算符定义为处理带符号的 32 位整数(从双精度浮点数的本机数字存储转换而来)。因此 1<<31 的结果一定是负数。

唯一使用无符号 32 位整数的 JavaScript 运算符是 >>。您可以利用此功能将您一直在使用其他按位运算符处理的有符号整数转换为无符号整数:

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

同时:

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

不起作用,因为所有移位操作仅使用最低的 5移位位(在 JavaScript 和其他类似 C 的语言中也是如此)。 <<32 等于<<0,即。没有变化。

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

The << operator is defined as working on signed 32-bit integers (converted from the native Number storage of double-precision float). So 1<<31 must result in a negative number.

The only JavaScript operator that works using unsigned 32-bit integers is >>>. You can exploit this to convert a signed-integer-in-Number you've been working on with the other bitwise operators to an unsigned-integer-in-Number:

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

Meanwhile:

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

won't work because all shift operations use only the lowest 5 bits of shift (in JavaScript and other C-like languages too). <<32 is equal to <<0, ie. no change.

故人爱我别走 2024-08-22 12:38:00

Douglas Crockford 认为按位运算符是 javascript 的糟糕部分之一:

在 Java 中,按位运算符处理整数。 JavaScript 没有整数。它只有双精度浮点数。因此,按位运算符将其数字操作数转换为整数,执行其操作,然后将它们转换回来。在大多数语言中,这些运算符非常接近硬件并且速度非常快。 在 JavaScript 中,它们距离硬件很远并且速度非常慢。JavaScript 很少用于进行位操作。

-- Douglas Crockford 在“JavaScript:优秀部分”中,附录 B,按位运算符(添加了重点)

您确定按位运算符确实可以加速您的逻辑吗?

Douglas Crockford believes that bitwise operators is one of the bad parts of javascript:

In Java, the bitwise operators work with integers. JavaScript doesn't have integers. It only has double precision floating-point numbers. So, the bitwise operators convert their number operands into integers, do their business, and then convert them back. In most languages, these operators are very close to the hardware and very fast. In JavaScript, they are very far from the hardware and very slow. JavaScript is rarely used for doing bit manipulation.

-- Douglas Crockford in "JavaScript: The Good Parts", Appendix B, Bitwise Operators (emphasis added)

Are you sure that bitwise operators really speed up your logic?

安稳善良 2024-08-22 12:38:00

使用>>而不是>>获得无符号右移而不是符号扩展右移。无论整数是否带符号,所有其他按位运算符的行为方式都相同。

你的代码破坏“当子网......小于2”是令人担忧的。听起来您可能有一些与整数符号无关的错误。

Use >>> instead of >> to get an unsigned right shift instead of a sign-extending one. All the other bitwise operators behave the same way regardless of whether ints are signed or not.

Your code breaking "when subnet ... is less than 2" is concerning. That sounds like you may have some bug unrelated to signedness of integers.

睫毛上残留的泪 2024-08-22 12:38:00

JavaScript 没有整数,所有数字实际上都是双精度数。

Mozilla 的 Javascript 1.5 Reference 建议只能使用按位运算安全地处理 32 位数字。

Javascript doesn't have integers, all numbers are actually doubles.

The Javascript 1.5 Reference by Mozilla suggests that one can only use bitwise-operations safely for 32 bit numbers.

笨死的猪 2024-08-22 12:38:00

以下是在 javascript 中将 ipv4 地址与无符号整数相互转换的两个函数:

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) );
}

Here are two functions that convert ipv4 addresses to/from unsigned integers in 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) );
}
对你而言 2024-08-22 12:38:00

您有哪些类型的 IP 地址? IPv4 仅使用 32 位地址,因此 JavaScript 应该没问题(使用 double 可以为您提供 52 位整数部分< /a>)。 IPv6 使用 128 位地址,因此您必须使用数组。我的猜测是其他东西坏了。

[编辑] 构建一个小型库,它使用两个整数的数组作为内部数据类型。

What kind of IP addresses do you have? IPv4 uses only 32bit addresses, so JavaScript should be fine (using double which gives you an 52bit integer part). IPv6 uses 128bit addresses, so you'll have to use an array. My guess is that something else is broken.

[EDIT] Build a small library which uses an array of two ints as the internal data type.

柠北森屋 2024-08-22 12:38:00

Javascript现在有一个bigint类型,你可以使用n后缀来组成这样的数字。

所以使用你的例子你可以这样做:

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

Javascript now has a bigint type, you can use the n suffix to make such a number.

So using your example you could do:

<body>
    
    <script type='text/javascript'>
    document.write( (1n << 30n) +"<br/>");
    document.write( (1n << 31n) +"<br/>");
    document.write( (1n << 32n) +"<br/>");
    </script>
    
    </body>
</html>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文