【问题标题】:Dollars and cents counter美元和美分柜台
【发布时间】:2018-11-16 22:00:46
【问题描述】:

所以我得到了一项任务,要编写一个计数器,将给定数量的美元和美分加在一起。我们获得了一个用于测试功能的测试类。

我们得到了以下提示:

public int dollars () //The dollar count. 
ensure: this.dollars () >= 0

public int cents () //The cents count. 
ensure: 0 <= this.cents() && this.cents() <= 99

还有:

public void add (int dollars, int cents) //Add the specified dollars and cents to this Counter. 
public void reset () //Reset this Counter to 0. 
ensure: this .dollars() == 0 && this.cents() == 0 

这是我当前的代码:

public class Counter {

    private float count;

    public Counter() {
        count = 0;
    }

    public int dollars() {
        if (this.dollars() >= 0) {
            count = count + Float.parseFloat(this.dollars() + "." + 0);
        } return 0;
    }

    public int cents() {
        if (0 <= this.cents() && this.cents() <= 99) {
            count = count + Float.parseFloat(+0 + "." + this.cents());
        } else if (100 <= this.cents()) {
            count = count + Float.parseFloat(+1 + "." + (this.cents() - 100));
        }
        return 0;
    }

    public void add(int dollars, int cents) {
        dollars = this.dollars();
        cents = this.cents();
    }

    public void reset() {
        count = 0;  
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
    }
}

我意识到我在这里犯了错误(据说是在浮动并试图计算浮动的美元和美分部分)。但我无法准确指出它失败的地方。

【问题讨论】:

  • 你的 main() 方法是空的,对于初学者来说。
  • 我不确定这对功能有何影响,因为测试类是从另一个类完成的。
  • 那你为什么有它?真正的问题是什么?
  • 问题太多:(1) 在dollars() 内部调用dollars() 导致无限递归(cents 相同)。 (2) 几乎在任何地方都向count 添加值,除了应该做的地方。可能还有更多。
  • @user3757962 提示:不要使用float 表示货币值。在这种情况下,您应该将字段 count 更改为 int 并计算美分的数量(将美元转换为美分,并在需要时将它们转换回来)

标签: java currency


【解决方案1】:
public final class Counter {

    private int cents;

    public int dollars() {
        return cents / 100;
    }

    public int cents() {
        return cents;    // if you want to retrun all centes
        // return cents % 100;    // if you want to return cents less than dollar
    }

    public void add(int dollars, int cents) {
        this.cents = dollars * 100 + cents;
    }

    public void reset() {
        cents = 0;
    }
}

金融编程的一个非常重要的规则:永远不要使用浮点数作为计价货币。你肯定很快甚至很快就会遇到问题。看我的例子,实际上你的计数器可以很容易地实现,只需将美分的数量保存为 int(我可以看到,你没有美分的一部分)。

附注未来的一招

假设您需要一个浮点值并支持对它们的所有标准数学运算,例如+,-,/,*。例如。美元和整数美分(如您的示例中),您不能(或不想)使用浮动操作。你应该怎么做?

只需保留整数值中的两个低位数字作为小数部分。那么我们以 12 美元的价格为例:

int price = 1200;    // 00 is reserverd for centes, , price is $12
price += 600;        // add $6, price is $18
price += 44;         // add $0.44, price is $18.55

int dollars = price / 100;   // retrieve total dollars - $18     
int cents = cents % 100;     // retrieve cents less than dollars - 44  

【讨论】:

  • “金融编程规则:”这不是关于金融编程的,它是初学者的简单作业,所以虽然这是一个很好的解决方案,但它没有达到目标,因为它对某人来说比不高级知道方法和成员的区别
  • 无论如何。国家货币不应该用浮动来完成!
  • 我当然不同意这一点。
【解决方案2】:
public class Counter {

    private int dollars = 0;
    private int cents = 0;

    public Counter(int dollars, int cents) {
        this.dollars = dollars;
        this.cents = cents;
    }

    Counter reset() {
        return new Counter(0, 0);
    }

    Counter add(int dollars, int cents) {
        if (dollars < 0 || cents < 0) {
            throw new IllegalArgumentException();
        }

        int dollarsToAdd = this.dollars + dollars;
        int centsToAdd = this.cents + cents;

        if (centsToAdd > 99) {
            dollarsToAdd += centsToAdd / 100;
            centsToAdd = centsToAdd % 100;
        }
        return new Counter(dollarsToAdd, centsToAdd);
    }

    public void print() {
        System.out.println(this.dollars + "." + this.cents);
    }

}

1) 使用两个计数器而不是一个。它使计算变得容易并避免了浮点问题。 (看看这个System.out.println(1.03 - .42);

2) 验证输入。无法添加负数。

3) cents/100 将返回完整美元的数量。由于将 int 除以 int 会删除小数点。

4) cents%100 将返回余数 - 转换为完整美元后剩余的美分。

5) 让我们让它不可变。它将避免并发问题。

【讨论】:

  • 很好的解决方案但是太高级了,跳过不可变/并发的东西并且没有抛出异常
【解决方案3】:

这里有一些有用的答案。我也意识到我没有正确理解这个任务(我认为我需要一个总金额而不是两个单独的柜台来存放美元和美分),因此我把它弄得比它需要的更难。

我的解决方案(使用提供的测试类验证可以工作)如下:

public final class Counter {

    private int dollars;
    private int cents;

    public int dollars() {

        return dollars;
    }

    public int cents() {
        return cents;
    }

    public void add(int dollars, int cents) {
        if (dollars >= 0) {
            if (0 <= cents && cents <= 99) {
                this.dollars += dollars;
                this.cents += cents;
            }
            if (this.cents > 100 | cents > 100) {
                this.dollars += this.cents / 100;
                this.cents = this.cents % 100;
            }
            if (this.cents == 100 | cents == 100) {
                this.dollars++;
                this.cents = this.cents - 100;
            }

        }
    }

    public void reset() {
        dollars = 0;
        cents = 0;
    }
}

【讨论】:

  • 查看我的答案。想想你的代码在增加超过 100 美分的情况下将如何工作?例如。添加 (1, 444);
  • 我明白你在说什么。 444 美分只会增加 1 美元并从 444 美分中减去 100 美分。我对此进行了过度简化,并将对其进行修复。谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-03-31
  • 1970-01-01
  • 2021-06-15
  • 1970-01-01
  • 1970-01-01
  • 2014-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多