0

基本上我的问题是:为什么我得到的价值是 130.00000000000003 而不是 130.0 ?

我只是输出了引擎盖下的所有内容,并希望它足够清楚。我知道很可能是字符串/浮点数导致了这种情况,但我不知道如何解决它。

我已经尝试过 parseFloat() 、 parseFloat().toFixed(1) 、 parseFloat().round(1) 但我仍然不断得到 .00000000000003。不总是,但有时。

代码 :

// ... 'cost' will be passed as a parameter to the function 

 totalBudget = parseFloat(document.getElementById('currentBudget').value);// e.g value ='4' 

 ni = parseFloat(totalBudget);
 cost = (cost).toFixed(1);
 alert("totalBudget " + totalBudget + "\nni " + ni + "\ncost " + cost);
 ni += parseFloat(cost);
 alert("ni " + ni);

 alert('\nni= ' + ni + '\ntotalBudget= ' + totalBudget + '\ncost=' + cost);

 var playerCost = parseFloat(document.getElementById('playerCost' + vTemp).value);
 playerCost = (playerCost).toFixed(1);
 alert('playerCost= ' + playerCost);
 alert('\nNow will subtract ');
 ni -= playerCost;
 alert('\nAfter Subtraction');
 alert('\nni= ' + ni + '\nplayerCost= ' + playerCost);


alert('-------'+
'\ncurrBudget= '+totalBudget+
'\nnew budget ni= '+ni+
'\nPlayer#:vTemp= '+vTemp+
'\nCurr player cost= '+playerCost+
'\nNew players cost= '+cost +
"\nParseFloat(playerCost)for curr player= "+parseFloat(playerCost));

输出:

 // If cost = 7.2 and playerCost= 7.1. Notice all floating values are super fine. 
    totalBudget 129.8
    ni 129.8
    cost 7.2

    totalBudget 129.8
    ni 129.8
    cost 7.2


    ni= 137
    totalBudget= 129.8
    cost=7.2

    plaerCost= 7.1

    Now will subtract 
    After Subtraction


    ni= 129.9
    playerCost= 7.1


    -------
    currBudget= 129.8
    new budget ni= 129.9
    Player#:vTemp= 8
    Curr player cost= 7.1
    New players cost= 7.2
    ParseFloat(playerCost)for curr player= 7.1

在不刷新页面的情况下,我在网站上做一些其他的操作

输出:

// If cost = 7.3 and playerCost= 7.2. Notice floating points are totally not fine. 
totalBudget 129.9
ni 129.9
cost 7.3

ni 137.20000000000002

ni= 137.20000000000002
totalBudget= 129.9
cost=7.3

plaerCost= 7.2

Now will subtract 

After Subtraction

ni= 130.00000000000003
playerCost= 7.2

-------
currBudget= 129.9
new budget ni= 130.00000000000003
Player#:vTemp= 8
Curr player cost= 7.2
New players cost= 7.3
ParseFloat(playerCost)for curr player= 7.2

然后我会得到“超出预算。请更换你的球员!” 错误原因 130.00000000000003 > 130.0

4

3 回答 3

2

在任何编程语言中使用(二进制)浮点进行“金钱数学”的尝试都注定要遭受这样的命运。浮点数涉及二进制分数,而不是十进制分数,因此不可避免地会引入这种异常。

请注意,toFixed()将浮点数转换为字符串。它并没有太大帮助。

编辑——一条评论正确地指出浮点格式不一定是二进制浮点格式。我认为旧的 IBM 大型机(据我所知可能是当前的 z 系列机器)使用 base-16 指数和(可能)base-16 尾数。然而,如今,IEEE-754 格式(无论好坏)非常普遍,它是 x86 机器使用的格式。GPU 不是(必须的;我认为 32 位 NVidia 浮点非常接近)所有 IEEE-754,但我所知道的都是二进制浮点系统。(具体来说,根据语言的定义,JavaScript 是二进制浮点数。)

再次编辑- Eric Postpischil 在下面的评论中教我:-)

于 2012-11-02T14:03:32.920 回答
2

这可能有点矫枉过正,但试试BigDecimal。浮点数不适合精确数学,并且 javascript 没有内置的“十进制”类型来处理它。

此外,如果精度不是什么大问题,请尝试toPrecision()方法。它只会切断你不需要的部分。

var a = 1.000000000000005;
var b = a.toPrecision(6); //returns a string
var c = parseFloat(b); //returns a number
alert(b); // shows 1.000000;
alert(c); // shows 1;

编辑:其实你应该没问题

function roundFloat(input, prec) {
    return parseFloat(input.toFixed(prec));
}

并将其用于需要四舍五入的数字。

于 2012-11-02T14:12:47.770 回答
0

如果你有一个有效的小数位,乘以 10,截断为整数并比较:

var budget = 130.00000000000003;
var c1 = Math.round(budget * 10);
var c2 = Math.round(130 * 10);

if (c1 > c2)
    do_something;
于 2012-11-02T14:22:53.557 回答