程序逻辑错误

时间:2012-04-26 19:19:57

标签: java floating-point

所以我现在正在读一本关于学习java的书,书中概述的程序给我带来了一些麻烦。特别是当我运行程序计算美元数量并从9.87改变我应该有的时候,我会得到改变,就像我输入9.86一样。但是当我键入9.86时,我得到了正确的更改量。据我所知,只有一些以.87结尾的金额才会发生,例如8.87,虽然它适用于6.87罚款。这是本书 java编程第8版的介绍,因为它是一本由专业人士编写的书,我对这个错误可能是什么感到困惑。我试过在cmd和eclipse中运行它,两者似乎都显示出错误。

PasteBin链接:

http://pastebin.com/CVssSUYp

3 个答案:

答案 0 :(得分:5)

我几乎可以肯定你对浮点数的工作原理认识不足。你不能再用二进制中的1/3来精确地表示0.1。然后,最重要的是,IEEE浮点数对于双精度数的精度不能超过17位。

这不是Java或您的代码中的错误。

Money是一个不应用十进制数表示的东西的典型例子。

使用整数美元和美分写一个Money类,并在学习足够的Java时使用它:

public class Money {
    private final int dollars;
    private final int cents;
    private final Currency currency;

    public Money(int dollars, int cents, Currency curr) {
        if (dollars < 0) throw new IllegalArgumentException("dollars cannot be negative");
        if (cents < 0) throw new IllegalArgumentException("cents cannot be negative");
        if (curr == null) throw new IllegalArgumentException("currency cannot be null");
        this.dollars = dollars; 
        this.cents = cents;
        this.currency = curr;
    }
    // more methods here.
}

答案 1 :(得分:0)

duffymo 是对的。 9.87 x 100 in float可能是986.999999999 ...当转换为整数时转换为986.

您可以在使用(int)进行类型转换之前使用Math.round()将浮点数舍入到最接近的整数。

import java.lang.Math;
...
int remainingAmount = (int)(Math.round(amount * 100));
...

产生正确的输出:

Your amount 9.87 consists of
        9 dollars
        3 quarters
        1 dimes
        0 nickels
        2 pennies

此致

曼尼

答案 2 :(得分:0)

尝试将金额设定为9.87,然后将其乘以100:

double amount=9.87;
System.out.println(amount*100);

之后,尝试打印相同的内容,但将其转换为int:

double amount=9.87;
System.out.println((int)amount*100);

转换为int只是删除末尾的小数(正如Hot Licks在评论中所说的那样)并且因为你不能准确地表示浮点数(正如duffymo在答案中所说的那样)你得到986而不是987作为你期待的。