技术
·
3 min read
·
- Views
🐛记录一个由JS浮点数精度引起的线上BUG
Copied
技术
·
3 min read
·
- Views
🐛记录一个由JS浮点数精度引起的线上BUG
Copied
很简单,仅仅是求一个发送率和下载率,并且保留四位小数
只写核心逻辑,对于无穷等一些边界情况就先不写了.
乍一看似乎没有问题,但是由于要格式化为百分比展示, 当我对结果乘100后就出现Bug了
对于 0.1+0.2 !== 0.3 这种常见面试题都背得滚瓜烂熟,但是当第一次实际遇到相关问题,还是不会注意到。(所有还是得有业务沉淀)
计算机使用二进制系统来表示和存储所有类型的数据,包括数字。对于整数,这种表示是直接且精确的。然而,对于非整数(即浮点数),情况就变得复杂了。计算机使用一种称为IEEE 754标准的格式来近似表示这些数。在这种表示中,一个数被分解为基数(mantissa)和指数(exponent),并且每部分都有其位数限制。这意味着只能使用有限数量的位来表示一个非常宽广的数值范围,导致某些数无法被精确表示。
当进行 0.8182 * 100 这样的运算时,0.8182 实际上可能是一个近似值。尽管 .toFixed(4) 方法将其格式化为字符串 "0.8182",看起来似乎是精确的,但在进行乘法运算之前,它必须被转换回浮点数。在这个转换过程中,原始的二进制表示(及其精度限制)重新发挥作用。
当这个近似的浮点数乘以 100 时,结果本身也是一个浮点数,因此同样受到二进制表示的限制。由于二进制系统无法精确表示某些十进制小数,这个计算结果可能不会正好是一个整数,即使我们期望它是 8182 的十分之一。这就是为什么结果可能是 81.82000000000001 而不是 81.82。
原本打算再用toFixed(2)来简单处理一下乘100后得到的数,但产品要求 整数就不要小数点后两位了
34 篇文章
53 个话题
- 次访问