研究javascript中位運算相關資料,對取反位運算很是不理解,不明白取反後為什麼不是最大數-目前的值,而是~8=-9,~-8=7?
因為 ~8 恰好是 -9 在計算機中的表示方式。 。 。 。 32位元無符號整數可以表示 0 ~ 2^32-1的正整數範圍,這樣可以表示2^32個整數。 0 ~ 2^32-1的正整数范围,这样可以表示2^32个整数。当作为有符号数的时候,不是把最高的比特位作为符号位,即 -1 不是直接把000..001 的最高bit置为 1 ,而是使用其 -1 + 2^32 = 2^32-1 对应的二进制数表示。这种形式叫做补码。一种最快的求负数补码的方式是,其绝对值的二进制,从低位开始,遇到的第一个 1 之前(包括这个1)不变,其他的 1 变 0, 0 变 1。 比如 -4 的补码是, 4 -> 00...0100 -> 11...1100當作為有符號數的時候,不是把最高的位元位當作符號位,即-1 不是直接把000..001 的最高bit置為1 ,而是使用其-1 + 2^32 = 2^32-1 對應的二進制數表示。這種形式叫做補碼。一個最快的求負數補碼的方式是,其絕對值的二進制,從低位開始,遇到的第一個 1 之前(包括這個1)不變,其他的 1 變 0, 0 變 1。 例如 -4 的補碼是, 4 -> 00...0100 -> 11...1100
0 ~ 2^32-1
2^32
-1
000..001
-1 + 2^32
2^32-1
00...0100
11...1100
這樣做的好處是,減少運算規則,對於加法和減法,計算機不必區分是不是有符號的。比如 4 位元的整形。 有符號的-5 + 4 = -1 二进制表示是 1011 + 0100 = 1111,而无符号的11+4=15二进制形式也是1011 + 0100 = 1111 。如果用1101 表示-5那么有符号加法就是1101 + 0100 = 1111,這樣,人看起來不方便,計算機也不方便。
-5 + 4 = -1
1011 + 0100 = 1111
11+4=15
1101
-5
1101 + 0100 = 1111
你說的對,去反就是最大的值-当前的值 这是对于无符号整数来说的。 只是除了>>> 之外,JS 位元運算子的回傳值,是有符號型的32位元整數。
最大的值-当前的值
>>>
function toUint32(x) {return x>>>0;} function toInt32(x) { return x>>0;} MaxUint32 = toUint32(-1);// -1 的二进制表示和 2^32 - 1 一样(32位整形来说) console.log(MaxUint32) // 4294967295 console.log(8 + toUint32(~8) === MaxUint32) // true console.log(7 + toUint32(~7) === MaxUint32) // true // 下面几个与本问题无关,就当是扩展了,自己试试输出是什么。 console.log(MaxUint32 + 1) console.log(toUint32(MaxUint32+1)) console.log(toUint32(MaxUint32+2))
取反?按位非吧,執行位元非的結果就是傳回數值的反碼。
因為這裡的按位取反並不是真正的按位取反,而是补码运算。
补码运算
具體的請參考這個問題:js中怎麼理解按位取反?
取反操作會將符號位也取反,詳見:《JavaScript 高階程式設計》3.5.2 位元操作運算
雷雷
因為 ~8 恰好是 -9 在計算機中的表示方式。 。 。 。
32位元無符號整數可以表示
0 ~ 2^32-1
的正整數範圍,這樣可以表示2^32
個整數。0 ~ 2^32-1
的正整数范围,这样可以表示2^32
个整数。当作为有符号数的时候,不是把最高的比特位作为符号位,即
-1
不是直接把000..001
的最高bit置为 1 ,而是使用其-1 + 2^32
=2^32-1
对应的二进制数表示。这种形式叫做补码。一种最快的求负数补码的方式是,其绝对值的二进制,从低位开始,遇到的第一个 1 之前(包括这个1)不变,其他的 1 变 0, 0 变 1。 比如 -4 的补码是, 4 ->00...0100
->11...1100
當作為有符號數的時候,不是把最高的位元位當作符號位,即-1
不是直接把000..001
的最高bit置為1 ,而是使用其-1 + 2^32
=2^32-1
對應的二進制數表示。這種形式叫做補碼。一個最快的求負數補碼的方式是,其絕對值的二進制,從低位開始,遇到的第一個 1 之前(包括這個1)不變,其他的 1 變 0, 0 變 1。 例如 -4 的補碼是, 4 ->00...0100
->11...1100
這樣做的好處是,減少運算規則,對於加法和減法,計算機不必區分是不是有符號的。比如 4 位元的整形。 有符號的
-5 + 4 = -1
二进制表示是1011 + 0100 = 1111
,而无符号的11+4=15
二进制形式也是1011 + 0100 = 1111
。如果用1101
表示-5
那么有符号加法就是1101 + 0100 = 1111
,這樣,人看起來不方便,計算機也不方便。你說的對,去反就是
最大的值-当前的值
这是对于无符号整数来说的。 只是除了>>>
之外,JS 位元運算子的回傳值,是有符號型的32位元整數。取反?按位非吧,執行位元非的結果就是傳回數值的反碼。
因為這裡的按位取反並不是真正的按位取反,而是
补码运算
。具體的請參考這個問題:js中怎麼理解按位取反?
取反操作會將符號位也取反,詳見:《JavaScript 高階程式設計》3.5.2 位元操作運算
雷雷