Java Double值= 0.01更改为0.009999999999999787

时间:2011-09-13 21:12:32

标签: java numbers double

  

可能重复:
  Why not use Double or Float to represent currency?

我正在为我的高中课程编写一个基本的Java命令行程序。我们现在只处理变量。它用于计算购买后更改中任何类型的账单和硬币数量。这是我的计划:

class Assign2c {
    public static void main(String[] args) {
        double cost = 10.990;
        int paid = 20;
        double change = paid - cost;
        int five, toonie, loonies, quarter, dime, nickel, penny;

        five = (int)(change / 5.0);
        change -= five * 5.0;

        toonie = (int)(change / 2.0);
        change -= toonie * 2.0;

        loonies = (int)change;
        change -= loonies;

        quarter = (int)(change / 0.25);
        change -= quarter * 0.25;

        dime = (int)(change / 0.1);
        change -= dime * 0.1;

        nickel = (int)(change / 0.05);
        change -= nickel * 0.05;

        penny = (int)(change * 100);
        change -= penny * 0.01;

        System.out.println("$5   :" + five);
        System.out.println("$2   :" + toonie);
        System.out.println("$1   :" + loonies);
        System.out.println("$0.25:" + quarter);
        System.out.println("$0.10:" + dime);
        System.out.println("$0.05:" + nickel);
        System.out.println("$0.01:" + penny);
    }
}

它应该都可以工作,但是在剩下0.01美元的最后一步,便士的数量应该是1但是,它是0.在进入代码并输出更改值到控制台几分钟后,我已经发现在变量= 0.01的最后一步,它变为0.009999999999999787。为什么会这样?

8 个答案:

答案 0 :(得分:8)

double用于货币是一个坏主意,Why not use Double or Float to represent currency?。我建议使用BigDecimal或以分为单位进行每次计算。

答案 1 :(得分:7)

0.01在浮点中没有精确的表示(对于这个问题,也没有0.1和0.2)。

你应该用整数类型做所有的数学运算,代表便士的数量。

答案 2 :(得分:4)

doubles内部不保留十进制,而是二进制。他们的存储格式相当于“100101乘以10000”(我正在简化,但这是基本的想法)。不幸的是,没有这些二进制值的组合精确到小数0.01,这是其他答案的意思,当他们说浮点数不是100%准确,或0.01没有精确的浮动表示点。

有多种方法可以解决这个问题,有些方法比其他方法更复杂。在您的情况下,最好的解决方案可能是在任何地方使用int并将值保持为美分。

答案 3 :(得分:1)

浮点数永远不会100%准确(不完全正确,请参阅下面的评论)。你永远不应该直接比较它们。也是整数舍入。做到这一点的最好方法可能是以美分计算,然后转换成美元(1美元= 100美分)。通过转换为整数,您将失去精确度。

答案 4 :(得分:1)

正如其他人已经说过的那样,不要使用双打进行财务计算。

本文http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html(每个计算机科学家应该知道的关于浮点算术的内容)是理解计算机中浮点数学的必读内容。

答案 5 :(得分:0)

它的浮动(双)

你不应该用它来计算金钱......

我建议使用int值并在pennys上运行

答案 6 :(得分:0)

这是一个多次出现的问题。底线是在使用二进制浮点(Java需要)的计算机上,只有分母为2的幂的分数才能精确表示。

同样的问题出现在十进制中。例如,1/3变为0.3333333 ...,因为3不是10的因子(我们在十进制中使用的基数)。同样是1 / 17,1,19等

在二进制浮点中,出现了同样的基本问题。主要区别在于十进制,因为5是因子10,所以1/5可以精确表示(因此可以是1/5的倍数)。由于5不是2的因子,因此不能以二进制浮点精确表示1/5

然而,与流行的看法相反,某些分数可以精确地表示 - 特别是那些分子只有2作为主要因子(例如,1/8或1/256)可以表示的分数精确地)。

答案 7 :(得分:0)

我确定你知道某些分数的十进制表示终止(例如.01)而有些则没有(例如2/3 = .66666 ......)。问题在于,根据您所处的基础,哪些分数会终止变化;特别是,.01不以二进制结束,因此即使double提供了很多精度,它也不能完全代表.01。正如其他人所说,使用BigDecimal或定点整数计算(将所有内容转换为美分)可能最适合货币;要了解有关浮点的更多信息,您可以从The Floating-Point Guide- What Every Programmer Should Know About Floating-Point Arithmetic开始。