js小数点保留时的四舍五入问题的处理

原创 Dean 工作笔记 二维码阅读
2018-10-31 22:29

现今很多网站在展示价格的时候都是保留两位来显示,这似乎已经成了一个惯例,在日常开发中,我们也经常会遇到这种问题,一般的数据都是比较正常的,比如$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,然后我们再还原数就得到了最后的结果。

本文地址:https://www.deanhan.cn/js-float-round.html
版权声明:本文为原创文章,版权归 Dean 所有,欢迎分享本文,转载请保留出处!
  • 支付宝二维码 支付宝
  • 微信二维码 微信