最近在工作过程中碰到一个隐藏的bug,经调试发现竟然是toFixed函数不可靠的结果引起的。后端同学在处理价格比较的时候,用foFixed进行价格的四舍五入之后,竟然发现比较的结果有问题;

大家都知道,Number类型的变量有个toFixed方法,该方法将Number四舍五入为指定小数位数的数字,以字符串返回。

IE:

0.6 .toFixed(0); // 0
1.6 .toFixed(0); // 2

Chrome:

0.6 .toFixed(0); // 1
1.6 .toFixed(0); // 2

另外还发现,就算是同在Chrome里,四舍五入也不靠谱:

( 0.035 ).toFixed( 2 ); // 0.04
( 0.045 ).toFixed( 2 ); // 0.04

这次IE倒是靠谱了:

( 0.035 ).toFixed( 2 ); // 0.04
( 0.045 ).toFixed( 2 ); // 0.05

结论 :toFixed()函数靠不住,如果有需要精确控制的情况,还是自己写个方法比较好。比如:

function toFixed(number, decimal) {
decimal = decimal || 0;
var s = String(number);
var decimalIndex = s.indexOf('.');
if (decimalIndex < 0) {
var fraction = '';
for (var i = 0; i < decimal; i++) {
fraction += '0';
}
return s + '.' + fraction;
}
var numDigits = s.length - 1 - decimalIndex;
if (numDigits <= decimal) {
var fraction = '';
for (var i = 0; i < decimal - numDigits; i++) {
fraction += '0';
}
return s + fraction;
}
var digits = s.split('');
var pos = decimalIndex + decimal;
var roundDigit = digits[pos + 1];
if (roundDigit > 4) {
//跳过小数点
if (pos == decimalIndex) {
--pos;
}
digits[pos] = Number(digits[pos] || 0) + 1;
//循环进位
while (digits[pos] == 10) {
digits[pos] = 0;
--pos;
if (pos == decimalIndex) {
--pos;
}
digits[pos] = Number(digits[pos] || 0) + 1;
}
}
//避免包含末尾的.符号
if (decimal == 0) {
decimal--;
}
return digits.slice(0, decimalIndex + decimal + 1).join('');
}
var a = 19.02
var b = 209.01
// 结果
console.log(toFixed(a, 2)); //==> 19.02
console.log(toFixed(b, 2)); //==> 209.01
console.log(Number(toFixed(a, 2)) < Number(toFixed(b, 2))); //==> true

toFixed方法的bug的更多相关文章

  1. Chrome/Firefox 中头toFixed方法四舍五入兼容性问题

    每个Number的toFixed()方法可把 Number 四舍五入为指定小数位数的数字.四舍五入顾名思义,4及以下舍去,5及以上加1. 四舍 1.31.toFixed(1) // 1.3 1.32. ...

  2. JS中toFixed()方法的问题及解决方案

    最近发现JS当中toFixed()方法存在一些问题,采用原生的Number对象的原型对象上的toFixed()方法时,规则并不是所谓的“四舍五入”或者是“四舍六入五成双”,所谓“四舍六入五成双”,在百 ...

  3. jquery的toFixed方法的正确使用

    最近一段时候公司的项目中遇到这么个事情,需要计算手续费,而这个手续费必须是保留小数点后面两位,且是由小数点后面第三位四舍五入,就这么个场景: 说说我计算的过程,下面是前两个数是测试用的: howMuc ...

  4. JavaScript toFixed() 方法

    定义和用法toFixed() 方法可把 Number 四舍五入为指定小数位数的数字. 语法NumberObject.toFixed(num) 参数 描述num 必需.规定小数的位数,是 0 ~ 20 ...

  5. tofixed方法 四舍五入

    tofixed方法 四舍五入 toFixed() 方法可把 Number 四舍五入为指定小数位数的数字.例如将数据Num保留2位小数,则表示为:toFixed(Num):但是其四舍五入的规则与数学中的 ...

  6. .NET压缩图片保存 .NET CORE WebApi Post跨域提交 C# Debug和release判断用法 tofixed方法 四舍五入 (function($){})(jQuery); 使用VUE+iView+.Net Core上传图片

    .NET压缩图片保存   需求: 需要将用户后买的图片批量下载打包压缩,并且分不同的文件夹(因:购买了多个用户的图片情况) 文章中用到了一个第三方的类库,Nuget下载 SharpZipLib 目前用 ...

  7. js toFixed()方法的坑

    javascript中toFixed使用的是银行家舍入规则. 银行家舍入:所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法. 简单来说就是:四舍六入五考虑,五后非零就进一,五后为零 ...

  8. toFixed()方法

    1.定义 toFixed() 方法可把 Number 四舍五入为指定小数位数的数字. 2.示例 Show the number 13.37 with one decimal: <script t ...

  9. JavaScript toFixed() 方法注意点

    定义和用法 toFixed() 方法可把 Number 四舍五入为指定小数位数的数字. 语法 NumberObject.toFixed(num) 参数 描述 num 必需.规定小数的位数,是 0 ~ ...

随机推荐

  1. DOM中表格的操作方法总结

    DOM中表格的操作方法总结 <table/>元素的方法如下: caption:指向<caption/>元素(如果存在): tBodies:<tbody/>元素的集合 ...

  2. hadoop故障及其应对

    为更好了解各种故障,可以修改数据块的大小和提升NameNode的日志级别 <property> <name>dfs.block.size</name> <va ...

  3. 数字证书签发,授权等相关以及https建立通信过程

    一直以来都对数字证书的签发,以及信任等事情一知半解.总算有个闲适的周末来总结和深入一下相关的知识. CA: CA(Certificate Authority)是证书的签发机构,它是负责管理和签发证书的 ...

  4. 网页性能优化之异步加载js文件

    一个网页的有很多地方可以进行性能优化,比较常见的一种方式就是异步加载js脚本文件.在谈异步加载之前,先来看看浏览器加载js文件的原理. 浏览器加载 JavaScript 脚本,主要通过<scri ...

  5. codeforces437C

    The Child and Toy CodeForces - 437C On Children's Day, the child got a toy from Delayyy as a present ...

  6. Apache虚拟主机

    基本概述 虚拟Web主机 在同一台服务器中运行多个Web站点,其中每一个站点并不独立占用一台真正的计算机 httpd支持的虚拟主机类型 基于域名的虚拟主机 基于IP地址的虚拟主机 基于端口的虚拟主机 ...

  7. Cuba项目配置IDEA,如何dubug

    1.在cuba中编辑端口,如下图: 2.在IDEA中添加一个远程链接,添加为对应的端口号,然后运行debug即可 如果两个端口号不对应,就会报出以下的错误:unable to open debugge ...

  8. 自学工业控制网络之路1.1-工业控制系统发展历程CCS DCS FCS

    返回 自学工业控制网络之路 自学工业控制网络之路1.1-工业控制系统发展历程CCS DCS FCS 工业控制系统是对诸如图像.语音信号等大数据量.高速率传输的要求,又催生了当前在商业领域风靡的以太网与 ...

  9. 【BZOJ3821/UOJ46】玄学(二进制分组,线段树)

    [BZOJ3821/UOJ46]玄学(二进制分组,线段树) 题面 BZOJ UOJ 题解 呜,很好的题目啊QwQ. 离线做法大概可以线段树分治,或者直接点记录左右两次操作时的结果,两个除一下就可以直接 ...

  10. CF1073E Segment Sum 解题报告

    CF1073E Segment Sum 题意翻译 给定\(K,L,R\),求\(L~R\)之间最多不包含超过\(K\)个数码的数的和. \(K\le 10,L,R\le 10^{18}\) 数位dp ...