位运算之补码
Posted 惜暮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了位运算之补码相关的知识,希望对你有一定的参考价值。
位运算之补码
位运算在我们开发工作中经常遇到,在一些性能优化的场景经常会出现位运算的场景,比如Java的HashMap里面就是不是通过取余操作而是通过 (n - 1) & hash
来计算key的index的(table array的length是2的n次方)。
程序中的整数在计算机内存中都是以二进制的形式存在的,位运算就是直接对整数在内存中对应的二进制位进行操作。
补码
首先需要补充一个背景知识:
- 正数的补码就是正数本身;
负数的补码 = 负数的绝对值取反 + 1
举个例子: 以int8为例:
- 15的的补码就是:
00001111
- -15的补码是:
11110001
我们分析下-15的补码是怎么算出来的:
- 取绝对值:|-15| = 15 ==
00001111
- 按位取反得到:
11110000
- 加一:
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)
:
- 7的补码加上 -3 的补码
00000111
(7的补码) +11111101
(-3的补码)00000111
+ ^(00000011
-1)
也就是负数的补码 = ^ (负数对应的正数-1)
。 这里的^是按位取反的意思。
以上是关于位运算之补码的主要内容,如果未能解决你的问题,请参考以下文章