为什么我的java更改/收银员计划会继续减少两美分?

时间:2014-02-07 14:56:32

标签: java rounding

我尝试过很多方法,比如math.Round,并将它们变成双打和整数,但我不知道为什么以及它最后会减少到2美分。当我购买32.27并用36支付答案是3美元2季度2角钱2美分。 这是我的代码:

import java.util.Scanner;

public class Change {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);


        System.out.print("Purchase: ");
        double purchase = input.nextDouble();
        System.out.print("Payment: ");
        double amountGiven = input.nextDouble();

        int remainingAmount = (int) ((amountGiven - purchase) * 100);


        int numOfDollars = remainingAmount / 100;
        remainingAmount = remainingAmount % 100;

        int numOfQuarters = remainingAmount / 25;
        remainingAmount = remainingAmount % 25;

        int numOfDimes = remainingAmount / 10;
        remainingAmount = remainingAmount % 10;

        int numOfPennies = remainingAmount;

        System.out.println("Given $ " + amountGiven + " for a purchase of $ " +
                purchase + " we need " + numOfDollars + " dollars " + numOfQuarters +
                " quarters " + numOfDimes + " dimes " +
                numOfPennies + " cents ");
    }
}

4 个答案:

答案 0 :(得分:1)

这种情况发生了,因为数量不能完全表示为双精度数。当你转换为int时,它会被截断。

如果以14位小数打印,则以美分为单位的更改金额为372.99999999999955。

使用BigDecimal或仅使用CurrencyInteger进行计算的自定义int类型。

答案 1 :(得分:1)

如果您运行此代码,您将看到问题所在:

final double purchase = 32.27;
System.out.println("Purchase: " + new BigDecimal(purchase));
final double diff = 36 - purchase;
System.out.println("Difference: " + new BigDecimal(diff));
System.out.println("Cent difference: " + (int)(100*diff));

输出

Purchase: 32.27000000000000312638803734444081783294677734375
Difference: 3.72999999999999687361196265555918216705322265625
Cent difference: 372

因此,您可以看到您的麻烦立即开始:小数值32.27由最近的double值表示,略大。然后差别是略小于,这在截断后下降了整整一分钱。

课程:不要将输入解析为double,而是into a BigDecimal

答案 2 :(得分:0)

此类型的计算从不使用原始类型。始终使用BigDecimal

答案 3 :(得分:0)

您不能进行除法导致整数类型的余数而不会丢失精度

double d1 = 32.27;
double d2 = 36;
int i1 = (int) (d1 * 100);
int i2 = (int) (d2 * 100);
int rad = (int) ((d1 - d2 ) * 100);
int rai = i1 - i2;
double rdd = (double)rai / 100; // <- this is what you are expecting
int ndi = rai / 100;            
//  ^ this is what you are getting 
//  int / int == double which gets silently truncated

System.out.println("i1 = " + i1);
System.out.println("i2 = " + i2);
System.out.println("rad = " + rad);
System.out.println("rai = " + rai);
System.out.println("rdd = " + rdd); // mostly accurate in this case
System.out.println("ndi = " + ndi); // truncated

OUPUTS

i1 = 3227
i2 = 3600
rad = -372
rai = -373
rdd = -3.73
ndi = -3