toFixed问题及解决方法
一. toFixed问题
发现在chrome里面0.725.toFixed() = 0.72,在IE下是0.73。
二. 网上大牛解决方法
网上大牛重写Number的toFixed方法。
网址:http://stackoverflow.com/questions/10470810/javascript-tofixed-bug-in-ie6
Number.prototype.toFixed = function(n) { var power = Math.pow(10, n); var fixed = (Math.round(this * power) / power).toString(); if(n == 0) return fixed; if(fixed.indexOf('.') < 0) fixed += '.'; var padding = n + 1 - (fixed.length - fixed.indexOf('.')); for(var i = 0; i < padding; i++) fixed += '0'; return fixed; };
0.725.toFixed(2)=0.73
298561.7249999999999999.toFixed(2)=298561.72
发现298561.725.toFixed(2)=298561.72还是不对。
三. 彻底解决方法
<html> <head></head> <script> /** * 浮点数乘法运算 * @param {number} arg1 乘数 * @param {number} arg2 被乘数 * @example * Math.floatMul(11.1, 77.7) * 其形式等同于 (11.1 * 77.7) 但不存在 JS 丢失精度的问题 * 如3.69 * 258.258 */ Math.floatMul = function(arg1, arg2) { var m=0, s1=arg1.toString(), s2=arg2.toString(); if(s1.indexOf('.') != -1) m += s1.split('.')[1].length; if(s2.indexOf('.') != -1) m += s2.split('.')[1].length; return Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m); }; /** * 浮点数除法运算 * @param {number} arg1 除数 * @param {number} arg2 被除数 * @example * Math.floatDiv(11.1, 77.7) * 其形式等同于 (11.1/77.7) 但不存在 JS 丢失精度的问题 * 如3.69 / 258.258 */ Math.floatDiv = function(arg1, arg2) { var t1=0, t2=0, r1, r2, s1=arg1.toString(), s2=arg2.toString(); if(s1.indexOf('.') != -1) t1 = s1.split('.')[1].length; if(s2.indexOf('.') != -1) t2 = s2.split('.')[1].length; r1 = Number(s1.replace('.', '')); r2 = Number(s2.replace('.', '')); return (r1 / r2) / Math.pow(10, t1 - t2); }; /** * 浮点数加法运算 * * @param {number} arg1 加数 * @param {number} arg2 被加数 * * @example * Math.floatAdd(11.1, 77.7) * 其形式等同于 (11.1 + 77.7) 但不存在 JS 丢失精度的问题 * 如694.84 + (-300) */ Math.floatAdd = function(arg1, arg2) { var r1, r2, m; try{ r1 = arg1.toString().split(".")[1].length; } catch(e) { r1 = 0; } try{ r2 = arg2.toString().split(".")[1].length; } catch(e) { r2 = 0; } m = Math.pow(10, Math.max(r1, r2)); return ((arg1 * m) + (arg2 * m)) / m; }; /** * 浮点数减法运算 * * @param {number} arg1 减数 * @param {number} arg2 被减数 * * @example * Math.floatSub(11.1, 77.7) * 其形式等同于 (11.1 - 77.7) 但不存在 JS 丢失精度的问题 * 如694.84 - 300 */ Math.floatSub = function(arg1, arg2) { var r1, r2, m, n; try{ r1 = arg1.toString().split('.')[1].length; } catch(e) { r1 = 0; } try{ r2 = arg2.toString().split('.')[1].length; } catch(e) { r2 = 0; } m = Math.pow(10, Math.max(r1, r2)); // use accurate one n = (r1 >= r2) ? r1 : r2; return (((arg1 * m) - (arg2 * m)) / m).toFixed(n); }; //http://stackoverflow.com/questions/10470810/javascript-tofixed-bug-in-ie6 Number.prototype.toFixed = function(n) { var power = Math.pow(10, n); var fixed = (Math.round(Math.floatMul(this, power)) / power).toString(); if (n == 0) return fixed; if (fixed.indexOf('.') < 0) fixed += '.'; var padding = n + 1 - (fixed.length - fixed.indexOf('.')); for (var i = 0; i < padding; i++) fixed += '0'; return fixed; }; /** * 计算方法 */ function calculate(){ var v1 = document.getElementById('txt1').value - 0; var v2 = document.getElementById('txt2').value - 0; var v = v1.toFixed(v2); alert(v1 + '.toFixed(' + v2 + ') = ' + v); } </script> <body> <div> <span>原值:</span> <input id="txt1" /><br/> </div> <div> <span>保留小数位数:</span> <input id="txt2" value="2"/> </div> <input type="button" value="计算" onclick="calculate()" /> </body> </html>
运行结果都OK。
有问题的测试结果
跟踪发现:
如下四种获取v1值的方法,298561.7249999999999999的结果都是298561.725
var v1 = parseFloat(document.getElementById('txt1').value); var v1 = Number(document.getElementById('txt1').value); var v1 = document.getElementById('txt1').value - 0; var v1 = Math.floatAdd(document.getElementById('txt1').value,0);