现今很多网站在展示价格的时候都是保留两位来显示,这似乎已经成了一个惯例,在日常开发中,我们也经常会遇到这种问题,一般的数据都是比较正常的,比如$25,我们让它展示成$25.00,$25.5我们让它展示成$25.50,数据存在多样性,运营人员一般肯定不会设置大于两个小数位的价格,但是如果再打个折呢?那就可能存在3位消暑甚至更多位小数,这个时候就会存在一个取舍的问题。
比如$25.554我们需要让它展示成$25.55,$25.556我们需要让它展示成$25.56,四舍五入嘛,但是据说银行对于价格在保留小数时的处理是4、5舍6入,也就是说$25.555实际展示的是$25.55而不是我们预想的$25.56,而且我们使用js的toFixed方法保留小数点似乎也是和银行遵循同样一个规则。$25.555在某些电脑上通过数字原生的toFixed方法保留小数点之后,实际得到的是$25.55,但是有时候我们就要展示真正的四舍五入怎么办呢?为了每个设备的统一,我们就需要造一个能真正做四舍五入保留小数位的函数,我们现将代码贴出来,再简单的说明一下:
function round(num, decimal) {
if (isNaN(num)) {
return 0;
}
const p1 = Math.pow(10, decimal + 1);
const p2 = Math.pow(10, decimal);
return Math.round(num * p1 / 10) / p2;
}
function toFixed(num, decimal) {
return round(num, decimal).toFixed(decimal);
}
上面有两个函数,round函数用于处理保留小数位时的四舍五入,返回结果是一个数字,所以我们还需调用toFixed方法来保留小数位。
对比一下看看效果:
2.555.toFixed(2); // 2.55
toFixed(2.555, 2); // 2.56
我们分别使用了原生的toFixed方法和我们自己编写的toFixed方法对2.555做保留两位小数位处理,在我电脑上显示的结果是不一样的,但是在有些电脑上结果可能是一样的。
然后我们在回到上面的round函数,p1、p2分别是什么意思呢?这个解释起来不太好说明,我们看一个演算就知道了:
2.555保留两位小数我们可以这样做:Math.round(2.555 * 1000 / 10) / 100,也许有朋友会疑惑,为什么不直接Math.round(2.555 * 100) / 100呢?而是先多乘一个10然后再除掉,因为这里涉及一个小数点精度问题,如果我们在控制台输入:
0.555 * 100
我们会发现结果并不是55.5,而是255.50000000000003,有些电脑可能是255.4999999999999999,总之不是一个整的,所以为了避免在我们保留到的小数位处出现精度问题,我们会乘一个10的需要保留小数位加1次幂的数然后再把多乘的10除掉,具体的值也就是上面的p1,然后我们再还原数就得到了最后的结果。