java float浮点型数据存储,丢失精度问题

Posted gson-and-nana

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java float浮点型数据存储,丢失精度问题相关的知识,希望对你有一定的参考价值。

java中float类型为4字节32位,内存中的存储遵循IEEE-754格式标准:

一个浮点数有2部分组成:底数m和指数e
底数m部分:使用二进制数来表示此浮点数的实际值。
指数e部分:占用8bit(1个字节)的二进制数,可表示数值范围为0-255。
但是指数可正可负,所以,IEEE规定,此处算出的次方必须减去127才是真正的指数。
所以,float类型的指数可从-126到128。
底数部分实际是占用24bit(3个字节)的一个值,但是最高位始终为1,所以,最高位省去不存储,在存储中占23bit。

所以一个浮点数的32位由三个部分组成:

1.第一位为符号位,表示改浮点数是一个正数还是负数,0为正,1为负;

2.第二到第九位共8为表示指数e,转成二进制需要+127(反之减去127);

3.后23位为底数,但是存储时自动省去了最高位的1,所以存储为23位实际为24位。(小数位置即为2^(23)=8388608       7位数  计算为6位数的精度)

 

举个栗子: 3.2f

转化为二进制存储:整数部分3  二进制  11 

           小数部分0.2  转化为二进制(乘2取整数部分直至小数部分为零) ---->(小数乘2)   0.4  0.8  1.6  1.2  0.4  0.8   1.6   1.2  0.4 ...... (无限循环)

         结果为:11.00 1100 11001100 11001100 11001100(由于位数有限,而小数部分无限循坏,这里已经丢失了精度)

         右移直到左边只剩一位 :1.100 1100 11001100 11001100 11001100 (右移了一位,可得到指数部分为1+127=128   1000 0000)

         最后得到二进制的存储 : 0 100 0000 0100 1100 11001100 11001100 (丢失精度)

 

反之转化为浮点数十进制:符号位0 :正数 

            指数 100 0000 0 即为128减去127 指数为1

            尾数部分:最高位1默认省去了加上小数点即为 1.100 1100 11001100 11001100

            正指数右移一位  11.0011 00110011 0011001100

            正数部分11---->3   底数部分   2^(-3)+2^(-4)+2^(-7)+2^(-8)+2^(-11)+2^(-12)+2^(-15)+2^(-16)+2^(-19)+2^(-20)






以上是关于java float浮点型数据存储,丢失精度问题的主要内容,如果未能解决你的问题,请参考以下文章

浮点型变量/常量

解惑剖析float型的内存存储和精度丢失问题

java丢失精度问题

java float double精度为啥会丢失

JavaJava_07 浮点型

Java中浮点型数据Float和Double进行精确计算的问题