位运算之补码
位运算之补码
位运算在我们开发⼯作中经常遇到,在⼀些性能优化的场景经常会出现位运算的场景,⽐如Java的HashMap⾥⾯就是不是通过取余操作⽽是通过 (n - 1) & hash 来计算key的index的(table array的length是2的n次⽅)。
程序中的整数在计算机内存中都是以⼆进制的形式存在的,位运算就是直接对整数在内存中对应的⼆进制位进⾏操作。
补码
⾸先需要补充⼀个背景知识:
负75的补码怎么求正数的补码就是正数本⾝;
负数的补码 = 负数的绝对值取反 + 1
举个例⼦: 以int8为例:
15的的补码就是: 00001111
-15的补码是:11110001
我们分析下-15的补码是怎么算出来的:
1. 取绝对值:|-15| = 15 == 00001111
2. 按位取反得到:11110000
3. 加⼀:11110001
我们设定:⼆进制中最⾼位为 0 代表正,为 1 则代表负。
理解计算机数值的加法
int8的整数为例,表⽰的数的范围是-128 ~ 127
(1)127+127
我们现在推倒127 + 127 的过程, 下⾯数值都⽤⼆进制表⽰
01111111 + 01111111 -> 11111110,
很明显,11111110因为第⼀个⼆进制位是1,所以是⼀个负数。
根据负数补码计算⽅法反推:原码的绝对值 = (补码 - 1,再求反)
所以:11111110的原码的绝对值 = 00000010,也就是int8的127 + 127最后结果是-2。
(2)127+127+127
前⾯已经得到127+127等于 -2。再加上127也就是:
11111110 + 01111111 = 01111101 (注意,超出8位的会溢出)
这明显是个正数,也就是125。
利⽤补码可以⽤加法来计算减法
还是基于int8来说。建设我们现在要计算 7-3,但是我们希望通过加法来计算减法。
也就是我们希望计算 7 + (-3):
1. 7的补码加上 -3 的补码
2. 00000111(7的补码) + 11111101(-3的补码)
3. 00000111 + ^(00000011 -1)
也就是负数的补码 = ^ (负数对应的正数-1) 。 这⾥的^是按位取反的意思。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。