首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >点后第16个元素的意外舍入

点后第16个元素的意外舍入
EN

Stack Overflow用户
提问于 2013-01-12 17:39:02
回答 2查看 83关注 0票数 0

可能重复: Moving decimal places over in a double

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

在看似随机的地方,成本将在圆点后面的第16个元素上舍入,这很奇怪,因为我使用的数字是1.00 (Vanilla)、1.10 (Chocolate)、0.30 (Sprinkles)、0.40 (WhippedCream)和0.35 (Nuts)。

为了重新创建它,您需要以下类和接口:

代码语言:javascript
复制
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());
    }
}

这将产生以下结果:

代码语言:javascript
复制
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

我不太愿意添加这么多代码,但考虑到错误似乎是随机出现的(一次是我添加了奶油,一次是我创建巧克力+坚果,两次是我添加了零星的代码),我无法确定代码的哪些部分是相关的,哪些是不相关的。

为什么它有时在任何地方都被声明为双倍,并且总是在圆点后面有2位数的数字?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-12 17:42:04

这就是浮点数(doublefloat)的现实.他们使用一个数学公式(我不详细介绍)来存储他们的数据,所以有些值不是你所期望的(这就是为什么银行和其他货币系统使用BigDecimal而不是double或其他类似的东西)。

因为,在您的例子中,您处理的是相当小的度量单位,所以我可能会把它简化为小数点。

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

代码语言:javascript
复制
String dblOutput = new DecimalFormat("#.##").format(icecream.getCost());
System.out.println("Cost: " + dblOutput + "\t" + "Description: " + icecream.getDescription());
票数 4
EN

Stack Overflow用户

发布于 2013-01-12 17:45:48

这只是浮点四舍五入的结果。请记住,在基数2中,一个很好的结束小数点,比如0.1,可能是一个无限重复的小数点。当小数点被四舍五入时,我们得到这些奇怪的舍入错误。

解决办法是永远不要直接打印浮点值。在DecimalFormat中使用Java.text或get货币实例来格式化(和舍入)输出

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14295996

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档