Double类型数值乘法运算出现异常行为问题咨询
为什么70D * 1.1 = 77.0,而50D * 1.1 = 55.00000000000001?(IEEE 754)
嘿,这个问题其实是IEEE 754浮点数标准的典型表现,咱们用大白话拆解一下:
核心原因:二进制没法精确表示所有十进制小数
计算机里的double类型(你写的D应该就是指这个双精度浮点数)是用二进制来存储数值的。但像1.1这种十进制小数,转换成二进制是无限循环小数——就像十进制里1/3=0.333...永远写不完一样,1.1的二进制是1.0001100110011...(循环节是0011)。
计算机没办法存储无限长的数,所以只能把它近似成一个有限长度的二进制数存起来。这个近似值和真实的1.1之间有一点点微小的误差,平时可能看不出来,但乘法运算后可能会把这个误差放大或者显现出来。
为什么两个乘法结果不一样?
- 对于
70D * 1.1:70的二进制是有限的(1000110),当它和那个近似存储的1.1相乘时,得到的结果刚好落在了double类型能精确表示的数值范围内,所以最终显示为精确的77.0。 - 对于
50D * 1.1:50的二进制是110010,和同一个近似1.1相乘后,理论上的结果55没法被double精确表示(因为浮点数的存储精度是有限的),计算机只能选择最接近这个真实值的可存储浮点数,也就是55.00000000000001——这个尾巴就是之前近似存储1.1带来的误差积累后的表现。
实用建议
这不是程序的bug,是浮点数的固有特性。如果是对精度要求极高的场景(比如货币计算),建议用整数来存储单位更小的数值(比如把元转成分,用整数存储分的数量),或者使用专门的高精度小数类型,彻底避免浮点数的近似误差问题。
内容的提问来源于stack exchange,提问作者mrcodename
相关产品推荐
相关产品推荐

