Java中double类型不准确原因之原码反码补码

一、原码

1)正数的原码就是它的本身

  假设使用一个字节存储整数,整数10的原码是:0000 1010

2)负数的最高位是符号位,不参与进制的换算

  假设使用一个字节存储整数,整数-10的原码是:1000 1010

二、反码

1)正数的反码就是它本身

用一个字节来存储一个整数,整数10的反码就是0000 1010

2)负数的反码就是按照它的原码按位取反,符号位(最高位)不变

比如-10的反码就是:1111 0101

三、补码

1)正数的补码和原码相同

假设使用一个字节存储整数,整数10的补码是:0000 1010(第三次强调:这一串是10这个整数在计算机中存储形式)

2)负数的补码是负数的反码加1

假设使用一个字节存储整数,整数-10的补码是:1111 0110(第三次强调:这一串是-10这个整数在计算机中存储形式)

介绍完原码反码补码之后

归根结底,这个问题涉及到二进制与十进制的转换!!

我们知道计算机进行的是二进制运算,我们输入的十进制数字会先转换成二进制,进行运算后再转换为十进制输出。

Double类型的数值占用64bit,即64个二进制数,除去最高位表示正负符号的位,在最低位上一定会与实际数据存在误差(除非实际数据恰好是2的n次方)。

如果这里不好理解,那我们再举个例子:如要用4bit来表示一个十进制小数3.26,从高到低位依次对应2的1,0,-1,-2次幂,根据最上面的分析,计算机内应当在二进制数11.01(对应十进制的3.25)和11.10(对应十进制的3.5)之间选择。显然这个区间里面除了我们需要的3.26,还有很多其他的数字。

再回到Double的64bit上来,同理:我们给出的数值,在大多数情况下需要比64bit更多的位数才能准确表示出来(甚至是需要无穷多位的,比如1/3),而Double类型的数值只有64bit,后面舍去的位数就一定会带来误差,无法得到“数学上精确”的结果。

posted @ 2022-09-10 18:10  -她的梦-  阅读(303)  评论(0编辑  收藏  举报