toFixed四舍五入为啥不准确
# toFixed 的问题
1.36.toFixed(1) // 1.4 没有问题
1.31.toFixed(1) // 1.3 没有问题
1.35.toFixed(1) // 1.4 这里的5入
1.45.toFixed(1) // 1.4 这里的5又舍去了。
1.15.toFixed(1) // 1.1 并没有进1 成1.2来凑偶数
1.05.toFixed(1) // 1.1 进1之后反倒成奇数了
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 原因
不是所谓的银行家算法,也不是四舍六入五成双,就是四舍五入
1.15.toPrecision(100)
// 1.149999999999999911182158029987476766109466552734375000000000000000000000000000000000000000000000000
1
2
2
1.15 在系统中就不是严格上的 1.15,通过这个高精度表示的数字来看,就知道为什么 1.15.toFixed(1) 的结果为什么是1.1了,因为小数点后第二位根本不是5而且4,所以直接舍去了
不管浏览器具体采用的是什么逻辑,通过 js 标准以及这些例子,可以确定 toFixed
方法使用的逻辑是四舍五入
,至于为什么部分数字不符合预期,是由于精度问题导致了。就好像为什么 0.1 + 0.2 !== 0.3
是一样的
运算前会转成二进制 误差的来源是在IEE 754 双精度浮点数标准下,二进制数据无法精确的标识小数(一些小数转换成二进制长度会无限循环)
# 解决方法
两个三方库:yatter
, decimal-format
import {toFixed} from 'yatter';
console.log(toFixed(87.55, 1)) // 87.6
1
2
3
2
3
import DecimalFormat from 'decimal-format';
const df = new DecimalFormat('0.0');
df.format(87.55); // 87.6
df.setRoundingMode(RoundingMode.HALF_EVEN); // 设置为 四舍六入五成双 模式
df.format(87.85) // 87.8
1
2
3
4
5
6
7
2
3
4
5
6
7
最近更新时间: 2025/05/09 09:02:23
- 01
- 2025/05/05 00:00:00
- 02
- 2025/05/01 00:00:00
- 03
- 2025/03/15 00:00:00