浮点数的二进制表示

在很多编程语言中,发现会出现0.1*3==0.3最后结果为false的情况,查了下资料记录为下:

1.浮点数的二进制表示

在编程语言中,类如java,js ,c ,数据都是以二进制的形式存在磁盘中的,数字也不列外,当计算机拿到一个数字存储时 ,会将数字转换成二进制存在磁盘中,所以我们首先弄清楚数字怎样转换为二进制:

  • 整数部分乘2取余后逆向排序
  • 小数部分乘以2取整数部分,知道小数部分为0为止,然后顺序排序

所以,0.1在计算机转换为二进制时不断进行乘2操作

  • 0.1×2 = 0.2 取0;
  • 0.2×2 = 0.4 取0;
  • 0.8×2 = 0.8 取0;
  • 0.6×2 = 1.6 取1;
  • 0.2×2 = 1.2 取1;
  • 0.1×2 = 0.2 取0;
    .....
    所以0.2在计算机中存储二进制位=>0.0001100110011...(循环0011)

而0.2在计算机转换为二进制时不断进行乘2操作

  • 0.2×2 = 0.4 取0;
  • 0.8×2 = 0.8 取0;
  • 0.6×2 = 1.6 取1;
  • 0.2×2 = 1.2 取1;
  • 0.1×2 = 0.2 取0;
    .....
    所以0.2在计算机中存储二进制位=>0.001100110011...(循环0011)

2.IEEE 754 规范

java语言采用的IEEE754的规范来存储浮点数,即float和double两种类型
float类型即具有24位有效数位,加上符号位1位+尾数23位 = 24位
因为float具有24位有效数位 ,除去1位符号位 即有23位存储位对应7~8位有效十进制数字
double类型即具有53位有效数位,加上符号位1位+尾数52位 = 53位
因为double具有24位有效数位 ,除去1位符号位 即有52位存储位对应15~16位有效十进制数字
0.1在计算机中有效存储为52位,即=> 0.00011001100110011001100110011001100110011001100110011001
0.2在计算机中有效存储为52位,即
=> 0.00110011001100110011001100110011001100110011001100110011
那么两者相加0.1的二进制+0.2的二进制
0.00011001100110011001100110011001100110011001100110011001

0.00110011001100110011001100110011001100110011001100110011
=
0.01001100110011001100110011001100110011001100110011001100
转换为10进制为0.30000000000000004!=0.3
所以在java ,js python c等编程语言中0.1+0.2!=0.3都是精度丢失的问题

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容