javascript里的安位非(~)运算
先看一下《高程》对于按位非的定义
按位非操作符由一个波浪线(~)表示,执行按位非的结果就是返回数值的反码。
然后《高程》上又说按位非的本质是:操作数的负值减一。
程序上的表现就是
console.log(~25) //-26
还是以25这个数值为例子
1
2
3
var num1 = 25; //二进制 0000 0000 0000 0000 0000 0000 0001 1001
var num2 = ~num1; //二进制 1111 1111 1111 1111 1111 1111 1110 0110
alert(num2); //-26
上面的例子我们无论如何也无法也25的反码和-26联系起来。
要解释这个,我得从计算机的 原码、反码、补码 说起
####原码
原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:
[+1]原 = 0000 0001
[-1]原 = 1000 0001
####反码
正数的反码是其本身.
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
####补码
正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补
关于原码、反码、补码 跟多的了解可以参看
原码、反码、补码 都是计算机对于有符号数的表示方式,后来补码因为解决了+0 和 -0 二进制表示不同的问题而被广泛运用。
所以现在计算机运算的时候都是使用数值的补码进行运算。那么~25 运算得到的其实是一串补码。
[1111 1111 1111 1111 1111 1111 1110 0110]补
[1111 1111 1111 1111 1111 1111 1110 0101]反
[1000 0000 0000 0000 0000 0000 0001 1010]原
-(2^4+2^3+2^1) = -26
这就是《高程》所说的『按位非的本质是:操作数的负值减一』的原理。