原码、反码和补码
这里不展开讲了,只是做个结论记录,网上文章多的是
正数的补码是其原码本身
负数的补码是其原码除符号位取反之后+1,
负数通过补码计算原码则是-1之后除符号位再取反。
为什么32位最大是-2147483648?
计算机中数值分为无符号和有符号,这里的符号是指是否将最高位当做符号位,如果是有符号则0表示正数,1表示负数;
比如4位二进制可以表示的无符号位是1111表示15,因此范围是[0,15]共16个数,那假如是有符号的情况呢?
最高位是符号位,那么正数最大是0111,表示为7,负数是1111,表示为-7,但是这种情况下存在+0和-0,即0000和1000两种零,为了额外的利用,则将-0认为是最小值再减1,即-8,因此4位二进制可以表示的范围是[-8,7];
同理,8位二进制表示的是[-128,127];而放到32位也是一样的情况
为什么要有补码?
在上一个问题中,其实我们在了解最高位1代表负数理解1111是-7还是很直白的,那为什么非要搞出一个补码呢?
我个人的理解在于二进制的计算,二进制是没有减法的,或者说数学的计算加减乘除都是靠加法器来实现的。
比如3+1,二进制就是0011+0001为0100是4;那3-1该如何表示呢?3+(-1),0011+1001最终是1111,变成了-7,这样不对;
那计算机怎么做呢?计算机利用补码的思想来处理。
还是3-1,我们想象为一个钟表,表的刻度是0-15,3-1的意思是逆时针往回拨动一格,也就是2,但是其实我们还可以顺时针拨动15格,也可以到2;这里就体现了在16(4位二进制)这个范围内,1和15是互补的。
因此在计算机里,减一个数,可以理解为加上他的补数
对于3-1来说,我们可以表示为3+15,即0011+1111,其实应该是10010,但是由于我们只有4位二进制位,最高位溢出了,所以最终是0010,也就是2;
这里15就是-1的补码,因此计算机用1111来表示-1;
那-1怎么就能用15或者说1111来表示呢?-2对应的是14,那就是1110,这期间怎么计算呢?
在10进制中,在16的范围内1和15互补我们是很好理解的,我们用16-1就能得到15,那将其转为二进制呢?
16的二进制表示是10000,1是0001,16-1就是(10000-0001)
但是首先这溢出了,其次二进制减法怎么搞,以前的科学家将其转换了一下
(10000-0001)
((1+1111)-0001)
(1+(1111-0001)),到这一步对于全1的被减数,本质上其实是取反操作,如果我们正着看其实是对0001取反再加1就是其补码
那另一个问题诞生了,补码1111代表-1,那最高位还算作符号位吗?或者说还是我们理解的符号位吗?经常有一种说法,正数的补码是其本身,负数的补码才需要额外计算又怎么理解呢?
这些问题的关键取决你统一以原码来看数值,还是以补码来看数值。
如果以原码来看,1是0001,-1是1001,最高位是符号位,好理解,但是无法参与运算。
如果以补码来看,1是0001,-1是1111,最高位依旧是符号位,高位为1的一定是负数。
0000-0111,代表1-7
1000代表-8
1001代表-7
1010代表-6
1111代表-1
计算机中对于有符号位统一是以补码存储的,因此不要错误的理解为正数是原码,负数是补码,其实都是补码。
参考:
惭愧!直到今天才真正明白为什么int型的取值范围是-2^31~2^31-1_int的取值范围为什么不对称-CSDN博客
补码原理——负数为什么要用补码表示_一个负数的补码不就是模数减去这个负数的绝对值吗?例如:如果模数是12,-4的补码一定是12-4=+8-CSDN博客