suchen

Heim  >  Fragen und Antworten  >  Hauptteil

Bitoperationen – Warum ~8=-9, ~-8=7 in Javascript?

Wenn ich relevante Informationen zu bitweisen Operationen in JavaScript studiere, verstehe ich die bitweise Inversionsoperation wirklich nicht. Ich verstehe nicht, warum es nach der Invertierung nicht die maximale Zahl ist – der aktuelle Wert, sondern ~8=-9, ~-. 8=7?

滿天的星座滿天的星座2745 Tage vor1002

Antworte allen(5)Ich werde antworten

  • PHPz

    PHPz2017-05-18 11:01:22

    因为 ~8 恰好是 -9 在计算机中的表示方式。。。。
    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

    这样做的好处是,减少运算规则,对于加法和减法,计算机不必区分是不是有符号的。比如 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))

    Antwort
    0
  • 巴扎黑

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

    取反?按位非吧,执行按位非的结果就是返回数值的反码。

    Antwort
    0
  • 给我你的怀抱

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

    因为这里的按位取反并不是真正的按位取反,而是补码运算

    具体的请参考这个问题:js中怎么理解按位取反?

    Antwort
    0
  • 阿神

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

    取反操作会将符号位也取反,详见:《JavaScript 高级程序设计》3.5.2 位操作运算

    Antwort
    0
  • 伊谢尔伦

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

    ~8=-9
    8的二进制 11000 =》第一位是符号位,正数1,负数0
    按位取反 =》所有位取反,再取补码
    11000 取反=》 00111 补码(负数的补码,符号位不动,其它取反+1)=》 01000+1 =》01001(-9)
    
    ~-8=7?
    -8的二进制 01000 =》第一位是符号位,正数1,负数0
    按位取反 =》所有位取反,再取补码
    01000 取反=》 10111 补码(正数的补码是其本身)=》 10111(7)
    

    Antwort
    0
  • StornierenAntwort