搜尋

首頁  >  問答  >  主體

位運算 - 在javascript中為什麼~8=-9,~-8=7?

研究javascript中位運算相關資料,對取反位運算很是不理解,不明白取反後為什麼不是最大數-目前的值,而是~8=-9,~-8=7?

滿天的星座滿天的星座2745 天前1001

全部回覆(5)我來回復

  • PHPz

    PHPz2017-05-18 11:01:22

    因為 ~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位元整數。

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

    回覆
    0
  • 巴扎黑

    巴扎黑2017-05-18 11:01:22

    取反?按位非吧,執行位元非的結果就是傳回數值的反碼。

    回覆
    0
  • 给我你的怀抱

    给我你的怀抱2017-05-18 11:01:22

    因為這裡的按位取反並不是真正的按位取反,而是补码运算

    具體的請參考這個問題:js中怎麼理解按位取反?

    回覆
    0
  • 阿神

    阿神2017-05-18 11:01:22

    取反操作會將符號位也取反,詳見:《JavaScript 高階程式設計》3.5.2 位元操作運算

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-05-18 11:01:22

    雷雷

    回覆
    0
  • 取消回覆