We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
由于计算机二进制环境下浮点数的计算精度缺失,导致我们用JS进行数据计算的时候会出现很多意想不到的情况:
console.log(70-67.9); //2.0999999999999943
我们预期的结果是2.1,结果却来了这么一大串…,为了达到预期的结果,我们可以采用以下解决方案:
console.log((70-67.9).toFixed(1)); //2.1
toFixed看似完美的解决了我们的问题,其实,坑才刚刚挖好:
整数也有小数点
console.log((70.9-67.9).toFixed(1)); //3.0
虽然是保留一位小数,但是3.0这种显示结果并不优雅,不过问题不大,简单处理一下即可:保留几(n)位小数我们就乘10n。
console.log((70.9-67.9).toFixed(1)*10/10); //3
属于银行家舍入法
银行家舍入:所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法。简单来说就是:四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一。
我们先看现状
console.log(0.005.toFixed(2)); // 0.01 正确 console.log(0.015.toFixed(2)); // 0.01 错误 console.log(0.025.toFixed(2)); // 0.03 正确 console.log(0.035.toFixed(2)); // 0.04 正确 console.log(0.045.toFixed(2)); // 0.04 错误 console.log(0.055.toFixed(2)); // 0.06 正确 console.log(0.065.toFixed(2)); // 0.07 正确 console.log(0.075.toFixed(2)); // 0.07 错误 console.log(0.085.toFixed(2)); // 0.09 正确 console.log(0.095.toFixed(2)); // 0.10 正确
虽然并不完全符合银行家舍入法的规则(不符合的原因应该是二进制下浮点数的坑导致的),但toFixed所存在的问题已经找到了。
重写toFixed方法解决以上两个问题:
Number.prototype.toFixed = function(length) { var carry = 0; //存放进位标志 var num,multiple; //num为原浮点数放大multiple倍后的数,multiple为10的length次方 var str = this + ''; //将调用该方法的数字转为字符串 var dot = str.indexOf("."); //找到小数点的位置 if(str.substr(dot+length+1,1)>=5) carry=1; //找到要进行舍入的数的位置,手动判断是否大于等于5,满足条件进位标志置为1 multiple = Math.pow(10,length); //设置浮点数要扩大的倍数 num = Math.floor(this * multiple) + carry; //去掉舍入位后的所有数,然后加上我们的手动进位数 var result = num/multiple + ''; //将进位后的整数再缩小为原浮点数 return result; }
下面我们来验证结果:
console.log(0.015.toFixed(2)); // 0.02 正确 console.log((70.9-67.9).toFixed(1)); //3 正确
调用重写方法,可以一劳永逸的解决toFixed存在的问题。当然,我们也有更直接的方法来处理,见方法2。
Math.round() 四舍五入取整
比如,0.015(num)需要保留两(n)位小数,可先将这个数乘以100(10*n),四舍五入取整后,再除以100(10*n)。
console.log(Math.round(0.015*100)/100); //0.02 Math.round(num*(10*n))/(10*n); //通用公式,n为要保留的小数位数
此方法简单快速,在数据处理比较少的地方很实用。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
由于计算机二进制环境下浮点数的计算精度缺失,导致我们用JS进行数据计算的时候会出现很多意想不到的情况:
我们预期的结果是2.1,结果却来了这么一大串…,为了达到预期的结果,我们可以采用以下解决方案:
toFixed看似完美的解决了我们的问题,其实,坑才刚刚挖好:
整数也有小数点
虽然是保留一位小数,但是3.0这种显示结果并不优雅,不过问题不大,简单处理一下即可:保留几(n)位小数我们就乘10n。
属于银行家舍入法
我们先看现状
虽然并不完全符合银行家舍入法的规则(不符合的原因应该是二进制下浮点数的坑导致的),但toFixed所存在的问题已经找到了。
重写toFixed方法解决以上两个问题:
下面我们来验证结果:
调用重写方法,可以一劳永逸的解决toFixed存在的问题。当然,我们也有更直接的方法来处理,见方法2。
Math.round() 四舍五入取整
比如,0.015(num)需要保留两(n)位小数,可先将这个数乘以100(10*n),四舍五入取整后,再除以100(10*n)。
此方法简单快速,在数据处理比较少的地方很实用。
The text was updated successfully, but these errors were encountered: