JavaScript:在不影响结果准确性的情况下舍入数字

JavaScript: Rounding number without impacting result accuracy

提问人:Eni Generalić 提问时间:10/1/2013 最后编辑:SergEni Generalić 更新时间:1/30/2014 访问量:1157

问:

问题:如果你这样做,你会得到的结果是 3 而不是 3。log1000log1000 = 2.9999999999999996

我试图在不影响结果准确性的情况下删除 JavaScript 函数中的此舍入错误。 在格式编号函数中,我测试了数字的“右尾”是否大于 epsilon(假设 epsilon 的值为 1e-9,如 C 所示)eval()FormatNumber(strnum)CheckEpsilon(strnum)

function FormatNumber(strnum) {
// asf - number format: automatic(0), scientific(1) or fixed(2) notation
// decimal - number of decimal places(0-15)

    // First we must check if the right tail is bigger than epsilon
    strnum = CheckEpsilon(strnum);
    // And then we format the number
    var x = parseFloat(strnum);

    switch(asf) {
        case 0:     // auto
            strnum = x.toPrecision();
            break;
        case 1:     // sci
            strnum = x.toExponential(decimal);
            break;
        case 2:     // fix
            strnum = x.toFixed(decimal);
            break;
    }

    return strnum;
}

function CheckEpsilon(strnum) {
// EPSILON  - Difference between 1 and the least value greater than 1 that is representable.

    var epsilon = 1e-8;
    var x = parseFloat(strnum);

    var expnum = x.toExponential(17);
    // Last 10 numbers before the exponent (9 if the number is negative)
    // we turn in to a new decimal number ...
    var y = parseFloat("0." + expnum.slice(9,19));

    // and then we compare it to epsilon (1e-8)
    // If y (or 1-y) is smaller than epsilon we round strnum
    if (y<epsilon || (1-y)<epsilon) {
        strnum = x.toExponential(10);
    }

    //and if it isn't, strnum is returned as normal
    return strnum;
}

如果你对这个函数的实际展示感兴趣,你可以看看我制作的计算器(它是用javascript制作的,所以你可以很容易地检查代码)。链接是:http://www.periodni.com/calculator.html

这就是我的做法,但我的实际问题是:有没有人知道更好的方法?

JavaScript 数字 eval 舍入 浮点精度

评论

3赞 T.J. Crowder 10/1/2013
“我试图在不影响结果准确性的情况下删除 JavaScript eval() 函数中的这个舍入错误。” 与此无关,只是IEEE-754双精度浮点数无法完美地代表每个值。eval

答:

0赞 ManelPNavarro 1/30/2014 #1

只需使用:toFixed(2)

var rounded = originalvar.toFixed(2);