Javascript中的数字和toFixed,toPrecision?

时间:2012-11-29 08:24:14

标签: javascript numbers

关于1.01+1.02 <{1}}的着名问题。2.0300000000000002

其中一个解决方法是使用toFixed:例如

(1.01+1.02).toFixed(2) --->"2.03"

但我看到了toPrecision的解决方案

parseFloat((1.01+1.02).toPrecision(10))-->"2.03"

但是让我们看看

中的n
  • toFixed(n)

  • toPrecision(n)

我怎么知道n是什么?

  0.xxxxxxxxxxx
+
  0.yyyyyyyyyyyyy
---------------------
  0.zzzzzzzzzzzzzzzzzzzzzzzzz
                ^ 
                |
-----??????------

添加的每个数字都可以有不同的十进制数字......

例如:

1.0002+1.01+1.03333 - &GT; 3.0435300000000005

我如何计算n?这(特定)问题的最佳做法是什么?

4 个答案:

答案 0 :(得分:1)

对于这种情况下的添加,我会检查每个操作数中的小数位数。

在最简单的情况下,操作数中小数位数最多的小数位数是n的值。

一旦有了这个,请使用您喜欢的任何方法来截断您的值。然后摆脱尾随的零。

在1.06 + 1.04等情况下你可能会遇到尾随零,第一步会将你带到1.10然后截断零会给出1.1

在您的上一个示例中,1.0002 + 1.01 + 1.03333最大小数位数为5,因此您将留下3.04353并且没有要截断的尾随零。

答案 1 :(得分:0)

返回预期输出:

function add(){
    // Initialize output and "length" properties
    var length = 0;
    var output = 0;
    // Loop through all arguments supplied to this function (So: 1,4,6 in case of add(1,4,6);)
    for(var i = 0; i < arguments.length; i++){
        // If the current argument's length as string is longer than the previous one (or greater than 0 in case of the first argument))
        if(arguments[0].toString().length > length){
            // Set the current length to the argument's length (+1 is to account for the decimal point taking 1 character.)
            length = arguments[0].toString().length +1;
        }
        // Add the current character to the output with a precision specified by the longest argument.
        output = parseFloat((output+arguments[i]).toPrecision(length));
    }
    // Do whatever you with with the result, here. Usually, you'd 'return output;'
    console.log(output);
}
add();                     // Returns 0
add(1,2,3);                // Returns 6
add(1.01,2.01,3.03);       // Returns 6.05
add(1.01,2.0213,3.3333);   // Returns 6.3646
add(11.01,2.0213,31.3333); // Returns 44.3646

parseFloat甚至可以为你排除零落。

此函数接受与您希望的参数一样多的数字,然后在添加它们时将这些数字的字符串长度加在一起。添加中使用的精度会动态修改,以适应“当前添加的”参数的长度。

Fiddle

答案 2 :(得分:0)

如果你正在进行计算,你有几个选择:

  • 将数字乘以例如100,转换为整数,然后进行计算,然后再转换回来
  • 进行计算,不要担心舍入错误,然后在显示时将结果四舍五入

如果您正在处理货币/货币,第一种选择可能不是一个糟糕的选择。如果你只是做科学数学,我个人不会担心它,只是在显示时将结果四舍五入,例如6个有效数字,这是我的c ++编译器的默认值(gcc;不确定它是否在是否符合c ++标准,但如果在gcc c ++中打印1.234567890,则输出为1.23457,并避免出现问题)

答案 3 :(得分:0)

var a = 216.57421;

a.toPrecision(1); // => '200' because 216 with 1 < 5;
a.toPrecision(2); // => '220' because 216 with 6 >= 5;

a.toFixed(1); // => 216.6 because 7 >= 5;
a.toFixed(2); // => 216.57 because 4 < 5;