Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在点后面的第16个元素处意外舍入_Java_Decorator_Rounding - Fatal编程技术网

Java 在点后面的第16个元素处意外舍入

Java 在点后面的第16个元素处意外舍入,java,decorator,rounding,Java,Decorator,Rounding,可能重复: 我正在创建装饰模式的基本实现,使用冰淇淋和补充剂作为主题。除了出现一些奇怪的输出行为外,一切都正常 在看似随机的地方,成本将在点后面的第16个元素处进行四舍五入输出,这很奇怪,因为我使用的数字是1.00(Vanilla)、1.10(Chocolate)、0.30(spreads)、0.40(WhippedCream)和0.35(Nuts) 为了重新创建,您需要以下类和接口: public interface Icecream { public double getCost(

可能重复:

我正在创建装饰模式的基本实现,使用冰淇淋和补充剂作为主题。除了出现一些奇怪的输出行为外,一切都正常

在看似随机的地方,成本将在点后面的第16个元素处进行四舍五入输出,这很奇怪,因为我使用的数字是1.00(
Vanilla
)、1.10(
Chocolate
)、0.30(
spreads
)、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
我不愿意添加这么多代码,但考虑到错误似乎是随机出现的(一次是我添加了鲜奶油,一次是我创建了巧克力+坚果,两次是我添加了Spreads),我无法真正确定代码中哪些部分是相关的,哪些部分不是相关的


为什么有时它会对一个到处都是双精度的数字进行舍入,并且总是在点后面有两位数字?

这就是浮点数(
double
float
)的实际情况。他们使用一个数学公式(我不详细说明)来存储数据,因此有些值并不完全符合您的预期(这就是为什么银行和其他货币系统使用
BigDecimal
而不是
double
或其他类似的东西)

因为,在你的例子中,你处理的是相当小的度量单位,我可能会把它四舍五入到一些小数位

下面是要输出的一小段代码,四舍五入到小数点后2位:

String dblOutput = new DecimalFormat("#.##").format(icecream.getCost());
System.out.println("Cost: " + dblOutput + "\t" + "Description: " + icecream.getDescription());

这就是浮点数(
double
float
)的实际情况。他们使用一个数学公式(我不详细说明)来存储数据,因此有些值并不完全符合您的预期(这就是为什么银行和其他货币系统使用
BigDecimal
而不是
double
或其他类似的东西)

因为,在你的例子中,你处理的是相当小的度量单位,我可能会把它四舍五入到一些小数位

下面是要输出的一小段代码,四舍五入到小数点后2位:

String dblOutput = new DecimalFormat("#.##").format(icecream.getCost());
System.out.println("Cost: " + dblOutput + "\t" + "Description: " + icecream.getDescription());

这只是浮点舍入的结果。请记住,在基数2中,一个漂亮的终止小数,如0.1,可能是一个无限重复的小数。当小数点四舍五入时,我们得到这些奇怪的四舍五入误差


解决方案是永远不要直接打印浮点值。使用Java.text中的DecimalFormat或get currency实例格式化(并舍入)输出

这只是浮点舍入的结果。请记住,在基数2中,一个漂亮的终止小数,如0.1,可能是一个无限重复的小数。当小数点四舍五入时,我们得到这些奇怪的四舍五入误差

解决方案是永远不要直接打印浮点值。在Java.text中使用DecimalFormat或获取currency实例来格式化(并舍入)输出