编辑:一个可能的解决方案: 我试图打印剩余的,我得到了这个: 3.75 1.75 0.75 0.25 0.049999997 0.029999997 0.009999998
0.04 和 0.02 我想是问题所在!
我的问题:
我必须用java写一个收银程序——我做的收银机只有以下注释:
例如:
输入:
price = 11.25
cash = 20
输出:
Five Francs, Two Francs, One Franc, Fifty Centimes, Twenty Centimes, Five Centimes
我的问题是我的代码给了我这个输出:
Five Francs, Teo Francs, One Franc, Fifty Centimes, Twenty Centimes, Two Centimes, Two Centimes
注意我如何得到 2 个二生丁而不是五生丁 所以我还差 1 生丁。
我用一个简单的循环和枚举解决了这个问题:
我的枚举:
public enum bill {
Fifty_Francs( 50.00f),
Twenty_Francs( 20.00f),
Ten_Francs( 10.00f),
Five_Francs( 5.00f),
Teo_Francs( 2.00f),
One_Franc( 1.00f),
Fifty_Centimes( 0.50f),
Twenty_Centimes( 0.20f),
Ten_Centimes( 0.10f),
Five_Centimes( 0.05f),
Two_Centimes( 0.02f),
One_Centime( 0.01f);
private final float value;
private final String description;
bill(float value) {
this.value = value;
this.description = " " + this.name().replace("_", " ");
}
public float getValue() {
return this.value;
}
@Override
public String toString() {
return this.description;
}
}
我的打印功能:
public static void getGhange(double price, double cash) {
if (cash < price){
System.out.println("Wrong buddy");
} else if (cash == price) {
System.out.println("Nothing");
} else { //CH > PP
float remaining = (float) (cash - price);
StringBuilder change = new StringBuilder();
for (bill d : bill.values()) {
while (remaining >= d.getValue()) {
remaining -= d.getValue();
change.append(d).append(',');
}
}
change.setLength(change.length() - 1); // remove , at the end
System.out.println(change.toString().trim());
}
}
答案 0 :(得分:2)
我建议你把所有的东西都乘以 100,并且只处理整数。
这样可以避免比较时的浮点不精确。
或者,您可以使用任意精度类型。
第一个建议的实施:
public class ShifraSec {
public static void main(String[] args) {
getGhange(11.25, 20);
}
public enum bill {
Fifty_Francs( 5000),
Twenty_Francs( 2000),
Ten_Francs( 1000),
Five_Francs( 500),
Two_Francs( 200),
One_Franc( 100),
Fifty_Centimes( 50),
Twenty_Centimes( 20),
Ten_Centimes( 10),
Five_Centimes( 5),
Two_Centimes( 2),
One_Centime( 1);
private final float value;
private final String description;
bill(float value) {
this.value = value;
this.description = " " + this.name().replace("_", " ");
}
public float getValue() {
return this.value;
}
@Override
public String toString() {
return this.description;
}
}
public static void getGhange(double price, double cash) {
int intPrice = (int)(price * 100);
int intCash = (int)(cash * 100);
if (intCash < intPrice){
System.out.println("Wrong buddy");
} else if (intCash == intPrice) {
System.out.println("Nothing");
} else { //CH > PP
int remaining = (intCash - intPrice);
StringBuilder change = new StringBuilder();
for (bill d : bill.values()) {
while (remaining >= d.getValue()) {
remaining -= d.getValue();
change.append(d).append(',');
}
}
change.setLength(change.length() - 1); // remove , at the end
System.out.println(change.toString().trim());
}
}
}
这是输出(我冒昧地将 Teo 法郎更改为两法郎): “五法郎,两法郎,一法郎,五十生丁,二十生丁,五生丁”
答案 1 :(得分:1)
处理金钱时,您应该使用专用库,或BigDecimal
。
使用 BigDecimal
您必须更改代码:
public static void getGhange(BigDecimal price, BigDecimal cash) {
if (cash.compareTo(price) < 0){
System.out.println("Wrong buddy");
} else if (cash.equals(price)) {
System.out.println("Nothing");
} else { //CH > PP
BigDecimal remaining = cash.subtract(price);
StringBuilder change = new StringBuilder();
for (bill d : bill.values()) {
while (remaining.compareTo(d.getValue()) >= 0) {
remaining = remaining.subtract(d.getValue(), new MathContext(2));
change.append(d).append(',');
}
}
change.setLength(change.length() - 1); // remove , at the end
System.out.println(change.toString().trim());
}
}
但现在它返回 Five Centimes
而不是 Two Centimes, Two Centimes, One Centime
,所以如果你需要 Five Centimes
你必须修改算法(但现在它可以按预期使用货币,浮点精度没有任何问题)
他的示例精度设置为 2 位数字 remaining.subtract(d.getValue(), new MathContext(2));
并且您的枚举方法返回值应该返回 BigDecimal
public BigDecimal getValue() {
return BigDecimal.valueOf(this.value);
}
答案 2 :(得分:0)
好的,我能够解决它,发现在 while 循环中使用 Math.round() 可以轻松解决它:
这一行:
remaining -= d.getValue();
变成这样:
remaining -= Math.round(d.getValue()*100) / 100.0
我使用的重要资源: https://java2blog.com/java-round-double-float-to-2-decimal-places/
答案 3 :(得分:0)
只需按照贡献者在上面给出的内容进行以下更改。
public static void getChange(double price, double cash) {
if (cash < price) {
System.out.println("Wrong buddy");
} else if (cash == price) {
System.out.println("Nothing");
} else { // CH > PP
float remaining = (float) (cash - price);
StringBuilder change = new StringBuilder();
for (bill d : bill.values()) {
while (remaining >= d.getValue()) {
remaining -= Math.round(d.getValue()*100.0)/100.0;
change.append(d).append(',');
}
}
change.setLength(change.length() - 1); // remove , at the end
System.out.println(change.toString().trim());
}
}
它会按预期结果,仍然使用其他可以使其更简单的方法。