#为什么是-128127?127
我们常说char类型数据占1个字节,范围是-128
OK,1字节八位,1位为符号为,7位存储数据,但是为什么负数要比正数多一个呢?
这涉及到补码和反码的概念,8位能表示2^8+1种变化(我更偏向于称它为变化,因为计算机中的二进制是我们赋予他的意义,这里+1指的是0)
也就是0255,256个数字,所以-128127是正确的
考虑一下0会如何被表示:
在符号位为正的情况下为 0000 0000
在符号位为负的情况下为 1000 0000
同样的数,他们表示方式重叠了,这显然不好
所以CPU采用了正数和负数表示方式不同的方法来解决这个问题
负数的表现方式为 补码: 反码 + 1
##反码
就和它的名字一样,它的意义是除符号位外,其他所有位取反
例如 0000 0000 取反为 0111 1111
##补码
补码即为反码 + 1
有了以上知识,那么可以得知以下二进制表示多少(假设为1 byte):
1111 1111 反码:1000 0000 补码:1000 0001 表示 -1
1000 0000 反码:1111 1111 补码:(这里不好表示o(* ̄▽ ̄*)ブ) 表示:-128
所以,为什么负数比正数多了一个呢?
因为计算机内部结构(补码)造成了负数比正数能多表达一个(这一个是来自于-0这个概念,因为我们更加偏向于+0而不是-0,
所以就让正数吃亏了,也不仅仅是这样,在很多我无法举例但的确存在的某些”骚操作”里面,这种方式给予了很大的支持)
这里也映射了很多概念,比如一个数已经表示最大了(比如char的127)我将它+1 为什么他表示了-128?
127二进制 0111 1111
+1之后 1000 0000(很熟悉吧,就在上面,这表示了负最大)
PS:底层的东西很有趣,不然为什么编译原理和操作系统凭什么被认为是程序三大浪漫(还有一个是图形学,
emmm 三大浪漫有很多争议,有些认为应当包含数据库和算法,新的三大浪漫还有人工智能和机器视觉等等)
PS:关于符号位扩展
思考下面代码
(x << 1) >> 1
x左移一位后又右移一位, 乍一看并没有什么改变, 这涉及到符号位的扩展问题
对于移位操作, 左移都补0, 而右移因为反码的关系:正数移位补0, 而负数移位补1, 所以当x左移改变了符号位时,再右移,它的值将会发生改变
具体改变的规律是符号位发生改变, 而数值上的体现涉及到负数会补码, 所以改变前后可能是两个看起来完全不同但其实有规律的值