voi*_*hos 20 javascript numbers operators bit-shift bitwise-operators
我最近发现了这段JavaScript代码:
Math.random() * 0x1000000 << 0
Run Code Online (Sandbox Code Playgroud)
我知道第一部分只是生成0到0x1000000(== 16777216)之间的随机数.
但第二部分似乎很奇怪.执行0位移位有什么意义?我不认为它会做任何事情.然而,经过进一步调查,我注意到0的偏移似乎截断了数字的小数部分.此外,无论是右移,左移,还是无符号右移,都无关紧要.
> 10.12345 << 0
10
> 10.12345 >> 0
10
> 10.12345 >>> 0
10
Run Code Online (Sandbox Code Playgroud)
我用Firefox和Chrome测试过,行为是一样的.那么,这个观察的原因是什么?它只是JavaScript的细微差别,还是也出现在其他语言中?我以为我理解了位移,但这令我感到困惑.
Ry-*_*Ry- 20
你是对的; 它用于截断值.
之所以>>有效,是因为它只能在32位整数上运行,因此值会被截断.(它也常用于像这样的情况,而不是Math.floor因为按位运算符具有较低的运算符优先级,所以你可以避免乱七八糟的括号.)
并且由于它仅在32位整数上运行,因此它也相当于具有0xffffffff舍入后的掩码.所以:
0x110000000 // 4563402752
0x110000000 >> 0 // 268435456
0x010000000 // 268435456
Run Code Online (Sandbox Code Playgroud)
但这不是预期行为的一部分,因为Math.random()它将返回0到1之间的值.
此外,它也是一样的| 0,这是更常见的.
Math.random()返回0(包括)和1(不包括)之间的数字.将此数字乘以整数会产生一个具有小数部分的数字.该<<操作员是用于消除小数部分的快捷方式:
所有位运算符的操作数都以big-endian顺序和二进制补码格式转换为带符号的32位整数.
上述语句意味着JavaScript引擎将隐式地将运算<<符的两个操作数转换为32位整数; 对于数字,它通过切掉小数部分来实现(不适合32位整数范围的数字不仅仅是小数部分).
它只是JavaScript的细微差别,还是也出现在其他语言中?
您会注意到松散类型语言中的类似行为.PHP例如:
var_dump(1234.56789 << 0);
// int(1234)
Run Code Online (Sandbox Code Playgroud)
对于强类型语言,程序通常会拒绝编译.C#这样抱怨:
Console.Write(1234.56789 << 0);
// error CS0019: Operator '<<' cannot be applied to operands of type 'double' and 'int'
Run Code Online (Sandbox Code Playgroud)
对于这些语言,您已经有了类型转换运算符:
Console.Write((int)1234.56789);
// 1234
Run Code Online (Sandbox Code Playgroud)
来自Mozilla的按位运算符文档(包括移位运算符)
所有位运算符的操作数都以big-endian顺序和二进制补码格式转换为带符号的32位整数.
所以基本上代码使用移位运算符的某种偶然方面作为由于移位0位而做的唯一重要的事情.伊克.
它只是JavaScript的细微差别,还是也出现在其他语言中?
我当然不能说所有语言,但Java和C#都不允许double值为左操作数和移位运算符.
| 归档时间: |
|
| 查看次数: |
5713 次 |
| 最近记录: |