精度损失:
计算机二进制有三种表示形式:原码、反码、补码。
三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同。(第一位是符号位不参与计算,后面的是数值位)
计算机在任何情况底层表示和数据存储都是补码形式。(所以说原码和反码都是过程码,都是为补码进行服务的,没有补码的话,原码和反码也就失去了存在价值!)
原码:计算机对数字二进制定点表示方法。
求正数的补码:和原码相同。
求负数的补码:负数(除了符号位以外)对应的二进制码所有二进制全部取反,再加1。
取反:将原码中0全部变成1,将原码中全部1变成0。
为什么会出现这种情况呢?既然有了原码为什么计算机底层存储还要使用补码形式来存储呢?
其实最主要的原因是,按照原码的表示形式,得到的负数原码和与之对应的正数原码相加,所到的结果并不是零!
按照只有原码的逻辑:
byte类型 4 的二进制为00000100
byte类型 -4 的二进制为10000100
两者相加得到:10001000 ——>结果为-8而不是0
所以只有原码的情况是无法解决负数问题的,那么
byte类型 4 的二进制为00000100
加上
byte类型-4 的二进制为????????
结果会是0呢?二进制表示00000000
答案是:
byte类型 4 的二进制为11111100
多次列举:
1的二进制:00000001
2的二进制:00000010
3的二进制:00000011
-1的二进制:11111111
-2的二进制:11111110
-3的二进制:11111101
所以总结负数的规律就是:先把十进制的负数取绝对值,然后再转换为二进制,然后按位取反,最后再+1
所以解决了负数问题的,那么就可以使用补码来解决数据在底层的存储问题了!
那么接下来看一下精度损失问题,
例如:byte取值范围是[-128,127]那么给byte赋值128和129会怎么样呢?
byte b1 = (byte)128;
byte是1字节的!
那么128的二进制补码是多少呢?
可以先看成127+1的形式,其对应补码相加为
01111111+00000001
得到补码:10000000
但是第一位是符号位,符号位为1,则说明是负数,那么就得按照负数的补码来倒推所对应的十进制数值。
所以先10000000减一,得到01111111
然后按位取反得到10000000
1在第八位上,则2的7次方为128
最后去绝对值,得到-128
byte b2 = (byte)129;
那么128的二进制补码是多少呢?
10000001
但是第一位是符号位,符号位为1,则说明是负数,那么就得按照负数的补码来倒推所对应的十进制数值。
所以先10000000减一,得到10000000
然后按位取反得到01111111
最后去绝对值,得到-127