我有以下代码:
var a = parseInt('010001',2);
console.log(a.toString(2));
// 10001
var b = ~a;
console.log(b.toString(2));
// -10010
〜在每个位上执行NOT运算符。不是产生倒置 a。的价值(a.k.a。的补充)。
010001 应该返回 101110 。
所以我无法理解我们如何才能获得 -10010 ?唯一可能的解释是:
010001被否定101110但是他写了-10001 然后由于一个不明原因,他给了我两个补充 和-10001变为-10010。
但是这一切在我的脑海里都是非常模糊的,你是否会对精确发生的事情有所了解。
答案 0 :(得分:3)
JavaScript的按位运算符将其操作数转换为32位有符号整数(通常为2's complement),执行其操作,然后将结果作为JavaScript数字类型中最合适的值返回(双精度浮点; JavaScript没有整数类型)。 §12.5.11 (Bitwise NOT Operator ~
)和§7.1.5 (ToInt32
)中的更多内容。
所以你的10001
是:
00000000 00000000 00000000 00010001
当~
为:
11111111 11111111 11111111 11101110
......在2s补码表示中确实是负数。
您可能想知道:如果位模式如上,那么为什么b.toString(2)
会给您-10010
?因为它显示了签名二进制文件,而不是实际的位模式。 -
表示否定,10010
表示18位小数。上面的位模式是用2s补码位表示的。 (是的,我做了必须自己检查一下!)
答案 1 :(得分:2)
在幕后,当Javascript执行按位操作时,它会转换为32位有符号整数表示,并使用它,然后将结果转换回其内部十进制表示。
因此,您的输入值010001
变为00000000 00000000 00000000 00010001
。
然后倒转:
~00000000 00000000 00000000 00010001 => 11111111 11111111 11111111 11101110
转换为十六进制,反转值为0xFFFFFFEE
,相当于-18的十进制值。
由于这是一个有符号整数,其值为-18,因此Javascript会将此值转换为-18的基础十进制表示。
当Javascript尝试将其打印为基数为2时,它会看到负号和值18,并将其打印为-10010
,因为10010
是正数的二进制表示18
答案 2 :(得分:1)
JavaScript使用32位有符号数字,所以
a (010001) (17) is 0000 0000 0000 0000 0000 0000 0001 0001
b = ~a (?) (-18) is 1111 1111 1111 1111 1111 1111 1110 1110
打印-18为-10010的原因以及获取实际值的方法在此处进行了解释Link
答案 3 :(得分:0)
根据Mozilla开发者网站here上的文档。按位注意任何数字x的产量 - (x + 1)。例如,~5产生-6。这就是为什么你在数字前面得到负号。