toFixed遇到了奇怪的问题

ddlucky 2014-07-08 11:02:58
今天客户打电话来说网页上有个地方计算不四舍五入了……

结果调试发现,4.25*13531.3=57508.025 ,.toFixed(2)结果竟然是57508.02
4.25*13531.42=57508.535 结果又是57508.54

……

这尼玛是玩我么……
...全文
387 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
ddlucky 2014-11-17
  • 打赏
  • 举报
回复
最后网上查了个加减乘除function,在计算时改为使用自定义function……问题解决……

    //除法函数,用来得到精确的除法结果
    //说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
    //调用:accDiv(arg1,arg2)
    //返回值:arg1除以arg2的精确结果
    function accDiv(arg1, arg2) {
        var t1 = 0, t2 = 0, r1, r2;
        try { t1 = arg1.toString().split(".")[1].length } catch (e) { }
        try { t2 = arg2.toString().split(".")[1].length } catch (e) { }
        with (Math) {
            r1 = Number(arg1.toString().replace(".", ""))
            r2 = Number(arg2.toString().replace(".", ""))
            return (r1 / r2) * pow(10, t2 - t1);
        }
    }

    //给Number类型增加一个div方法,调用起来更加方便。
    Number.prototype.div = function (arg) {
        return accDiv(this, arg);
    }

    //乘法函数,用来得到精确的乘法结果
    //说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
    //调用:accMul(arg1,arg2)
    //返回值:arg1乘以arg2的精确结果
    function accMul(arg1, arg2) {
        var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
        try { m += s1.split(".")[1].length } catch (e) { }
        try { m += s2.split(".")[1].length } catch (e) { }
        return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m)
    }

    //给Number类型增加一个mul方法,调用起来更加方便。
    Number.prototype.mul = function (arg) {
        return accMul(arg, this);
    }

    //加法函数,用来得到精确的加法结果
    //说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
    //调用:accAdd(arg1,arg2)
    //返回值:arg1加上arg2的精确结果
    function accAdd(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
    }

    //给Number类型增加一个add方法,调用起来更加方便。
    Number.prototype.add = function (arg) {
        return accAdd(arg, this);
    }
xuzuning 2014-07-08
  • 打赏
  • 举报
回复
0.00 : 0
0.00 : 0.005
0.01 : 0.01
0.02 : 0.015
0.02 : 0.02
0.03 : 0.025
0.03 : 0.030000000000000002
0.04 : 0.035
0.04 : 0.04
0.05 : 0.045
0.05 : 0.049999999999999996
0.05 : 0.05499999999999999
0.06 : 0.05999999999999999
0.06 : 0.06499999999999999
0.07 : 0.06999999999999999
0.08 : 0.075
0.08 : 0.08
0.09 : 0.085
0.09 : 0.09000000000000001
0.10 : 0.09500000000000001
不过是个计算精度问题
xuzuning 2014-07-08
  • 打赏
  • 举报
回复
for(i=0; i<0.1; i+=0.005)
  document.write(i.toFixed(2) + ' : ' + i + '<br>');
for(i=0; i<0.1; i+=0.005)
  document.write(i.toFixed(2) + ' : ' + i + '<br>');
Go 旅城通票 2014-07-08
  • 打赏
  • 举报
回复
要有人回复你才能结贴,要不只能无满意答案结贴
ddlucky 2014-07-08
  • 打赏
  • 举报
回复
好吧……我知道为什么了……老老实实的重写Number.prototype.toFixed()好了…… 不过怎么结帖呢……
XZowie 2014-07-08
  • 打赏
  • 举报
回复
SORRY 我貼錯了

function toFixed(n) {
    return (new RegExp("\\d+(\\.\\d{0,"+n+"})?")).exec(this.toString())[0] - 0;
}
Number.prototype.toFixed = toFixed;
XZowie 2014-07-08
  • 打赏
  • 举报
回复
咦…等等 不四舍五入了 可是js 的 toFixed 本是是四捨五入的函數說…重寫個吧
function toFixed(n) {
    return /\d+(\.\d{0,2})?/.exec(this.toString())[0] - 0;
}
Number.prototype.toFixed = toFixed;
XZowie 2014-07-08
  • 打赏
  • 举报
回复
原生的toFixed是沒有問題的
引用 楼主 ddlucky 的回复:
今天客户打电话来说网页上有个地方计算不四舍五入了…… 结果调试发现,4.25*13531.3=57508.025 ,.toFixed(2)结果竟然是57508.02 4.25*13531.42=57508.535 结果又是57508.54 …… 这尼玛是玩我么……
用js來計算 4.25*13531.3 = 57508.024999999994 .toFixed(2) 結果 57508.02 4.25*13531.42 = 57508.535 .toFixed(2) 結果57508.54 以toFixed的結果來說結果是正確的.. 沒辦法…js的計算本身就是不精確的
上海程序员3 2014-07-08
  • 打赏
  • 举报
回复
你的意思是原生的toFixed有问题? 如果真有的话,可能是因为二进制计算的问题,也就是说的计算结果可能是如下 4.25*13531.3=57508.0249999999...

87,910

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧