在阅读某段源码的时候读到了这么一段求绝对值的代码:
function fastAbs(value)//求绝对值
{
return (value ^ (value >> 31)) - (value >> 31);
}
然后在查阅资料后得到了原理:
对于32位机,
如果value是正数,右移31位之后就变成了0x00000000,
value和0x00000000异或,仍然是value,
异或之后的value-0x00000000仍然是value,
这样就完成了
如果value是负数,右移31位就变成了0xffffffff,
value和0xffffffff异或,变成了value连着符号位全部取反,也就是实现了补码取反,
补码取反-0xffffffff也就是补码取反再+1,是就上就对应着value的绝对值,
因为这里value和value的绝对值实际上只有最高位,也就是符号位不同,
这样移位就可以将最高位的符号位1变成0,实现绝对值的快速计算。
附原码、补码、反码的计算:
正数的原码、补码、反码都一样,负数的原码在正数的基础上将最高位改为1,而负数的反码是其原码除符号位外所有位取反,负数的补码是其反码加1,+0(正0)的原码、补码、反码都是0x00000000,-0(负0)的原码为1000 0000 0000 0000 0000 0000 0000 0000,-0(负0)的反码为1111 1111 1111 1111 1111 1111 1111 1111,补码为0000 0000 0000 0000 0000 0000 0000 0000。也就是实际上+0和-0的原码反码是不一样的,在计算机中数字的存储形式为补码。