javascript、typescript 保留两位或n位小数,包括四舍五入 和 不四舍五入进位
四舍五入
1. toFixed(n)
一般保留小数基本会先想到用toFixed(x),x区间[0,20],但会四舍五入,返回的是字符串
letnum=3.141592653;letn=num.toFixed(3);// "3.142"2. toPrecision(n)
toPrecision(x),x区间[0,21],和上面的方法一样,但是会包括整数位,所以区间+1
letnum=3.141592653;letn=num.toPrecision(4);// "3.142"3. Math.round
直接取整,配合乘除保留任意位。
letnum=3.141592653;letn=Math.round(num*1000)/1000;// 3.142逼逼这么多,你是不是想找不进位的方法,它来了
4. 作为额外思路,你当个玩具多取一位然后再截取就完事,如果一直进位那你就自行扩展到要截的那位即可
letnum=3.141592653;letn=num.toFixed(3).slice(0,-1);// "3.14"// 评论区已经举了反例:1.999.toFixed(3) → "2.000" → slice(0,-1) → "2.00"(错误,应该是 "1.99")//之前没写完就没登上来看,没及时看到反馈(找借口),我的问题//你可以先转string然后再截,但应该也有点问题,不纠结,用下面的5. Math.floor
letnum=3.141592653;letlen=2;letp=Math.pow(10,len);// num(3.141592653)取2位: 3.14// num(3.9999)取2位 : 3.99letn=Math.floor(num*p+1e-12)/p;// 1e-12 防浮点误差,银行家算法精度问题,为什么是这个值,可以拉到最后直接复制去用
/** 保留 len 位小数,round=true 四舍五入,false 截断 */publicfixedNum(num:number,len:number,round:boolean=true):number{letp=Math.pow(10,len);letv=num*p+1e-12;return(round?Math.round(v):Math.floor(v))/p;}1e-12 是怎么来的(摘抄)
JS 浮点是 IEEE 754 双精度,53 位尾数 ≈ 15~17 位十进制有效位。
num * p的误差量级 ≈|num * p| × Number.EPSILON(EPSILON ≈ 2.22e-16)。
例:3.14 * 100 = 313.99999999999994 误差 ≈ 314 × 2.22e-16 ≈ 7e-14 1e-12 ≈ 0.000000000001 7e-14 ≈ 0.00000000000007 //比补偿值小两个量级 1e-12 >> 7e-14 //够盖住误差选值区间:
- 上限:<
1 / 10^digits(超过会改变计算结果) - 下限:>
|num * p| × Number.EPSILON(小于这个补不动)
1e-12 是通用值,想精可以用|num * p| * Number.EPSILON * 10