java在点后面的第16个元素处意外四舍五入
Possible Duplicate:
Moving decimal places over in a double
我正在创建装饰模式的基本实现,使用冰淇淋和补充剂作为主题。除了出现一些奇怪的输出行为外,一切都正常
在看似随机的地方,成本将在点后面的第16个元素处进行四舍五入输出,这很奇怪,因为我使用的数字是1.00(Vanilla
)、1.10(Chocolate
)、0.30(Sprinkles
)、0.40(WhippedCream
)和0.35(Nuts
)
为了重新创建它,您需要以下类和接口:
public interface Icecream {
public double getCost();
public String getDescription();
}
public class Vanilla implements Icecream {
@Override
public double getCost() {
return 1.00;
}
@Override
public String getDescription() {
return "Vanilla ice";
}
}
public class Chocolate implements Icecream {
@Override
public double getCost() {
return 1.10;
}
@Override
public String getDescription() {
return "Chocolate ice";
}
}
public abstract class Decorator implements Icecream{
protected Icecream decoratedIcecream;
public Decorator(Icecream decoratedIcecream) {
this.decoratedIcecream = decoratedIcecream;
}
public abstract double getCost();
public abstract String getDescription();
}
public class Sprinkles extends Decorator {
public Sprinkles(Icecream decoratedIcecream) {
super(decoratedIcecream);
}
@Override
public double getCost() {
return decoratedIcecream.getCost() + 0.30;
}
@Override
public String getDescription() {
return decoratedIcecream.getDescription() + ", Sprinkles";
}
}
public class WhippedCream extends Decorator {
public WhippedCream(Icecream decoratedIcecream) {
super(decoratedIcecream);
}
@Override
public double getCost() {
return decoratedIcecream.getCost() + 0.40;
}
@Override
public String getDescription() {
return decoratedIcecream.getDescription() + ", Whipped cream";
}
}
public class Nuts extends Decorator {
public Nuts(Icecream decoratedIcecream) {
super(decoratedIcecream);
}
@Override
public double getCost() {
return decoratedIcecream.getCost() + 0.35;
}
@Override
public String getDescription() {
return decoratedIcecream.getDescription() + ", Nuts";
}
}
public class StartUp {
public static void main(String[] args) {
Icecream icecream = new Vanilla();
showDetails(icecream);
icecream = new Sprinkles(icecream);
showDetails(icecream);
icecream = new WhippedCream(icecream);
showDetails(icecream);
Icecream icecream2 = new Nuts(new Chocolate());
showDetails(icecream2);
icecream2 = new Sprinkles(icecream2);
showDetails(icecream2);
Icecream icecream3 = new Vanilla();
showDetails(icecream3);
icecream3 = new Nuts(icecream3);
showDetails(icecream3);
icecream3 = new Sprinkles(icecream3);
showDetails(icecream3);
}
private static void showDetails(Icecream icecream){
System.out.println("Cost: " + icecream.getCost() + "\t" + "Description: " + icecream.getDescription());
}
}
这将产生以下输出:
Cost: 1.0 Description: Vanilla ice
Cost: 1.3 Description: Vanilla ice, Sprinkles
Cost: 1.7000000000000002 Description: Vanilla ice, Sprinkles, Whipped cream
Cost: 1.4500000000000002 Description: Chocolate ice, Nuts
Cost: 1.7500000000000002 Description: Chocolate ice, Nuts, Sprinkles
Cost: 1.0 Description: Vanilla ice
Cost: 1.35 Description: Vanilla ice, Nuts
Cost: 1.6500000000000001 Description: Vanilla ice, Nuts, Sprinkles
我不愿意添加这么多代码,但考虑到错误似乎是随机出现的(一次是在我添加鲜奶油时,一次是在我创建巧克力+坚果时,两次是在我添加洒料时),我无法真正确定代码中哪些部分是相关的,哪些部分不是相关的
为什么它有时会对一个到处都是双精度的数字进行取整,并且总是在点后面有两位数
# 1 楼答案
这只是浮点舍入的结果。请记住,在基数2中,一个很好的终止小数,比如0.1,可能是一个无限重复的小数。当小数点四舍五入时,我们得到这些奇怪的四舍五入误差
解决方案是永远不要直接打印浮点值。在Java中使用DecimalFormat。文本或获取货币实例以格式化(并四舍五入)输出