JavaScript多位小数数值异常:游戏购买逻辑数值大于1后判定失效
问题原因解答
这个问题是JavaScript中Number类型遵循IEEE 754双精度64位浮点数标准的精度特性导致的,本质是浮点数运算的精度丢失问题,具体原因如下:
- 首先你看到的界面数值和实际存储值不一致:你调用
.toFixed(11)展示的数值是经过四舍五入/截断处理后的结果,并不是totalMoney和itemCost两个变量在内存中存储的真实值。 - 浮点数精度的分配逻辑:64位浮点数包含1位符号位、11位指数位、52位尾数位,能表示的有效十进制数字约为16~17位。当数值处于0到1区间时,整数位为0,所有有效位都可以用来存储小数部分,你用到的11位小数完全在精度覆盖范围内,多次运算也不会出现可见的误差,所以逻辑运行正常。
- 大于1后出现误差的原因:当数值大于1后,整数部分会占用部分有效位,留给小数部分的有效位相应减少。你多次执行减法、翻倍乘法操作后,累计的精度误差会让
totalMoney的实际存储值比界面展示的要小,刚好小于itemCost的实际存储值,就会出现界面看起来钱够、但判定不通过的情况。
修复建议
最简单的规避方案是改用整数存储货币的最小单位:你的初始货币是1e-8,可以把所有数值统一乘以1e8转成整数做运算,展示的时候再除以1e8格式化为小数,完全避免浮点数运算的精度误差。
内容的提问来源于stack exchange,提问作者Jacob F
相关产品推荐
相关产品推荐

