Счетчик долларов и центов

Итак, я получил задание написать счетчик, который складывает заданное количество долларов и центов. Нам дали тестовый класс, который используется для проверки функциональности.

Нам дали следующие подсказки:

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() пуст.

shmosel 16.11.2018 23:02

Я не уверен, как это повлияет на функциональность, поскольку тестирование класса выполняется из другого класса.

user3757962 16.11.2018 23:10

Тогда зачем она тебе? А в чем собственно проблема?

shmosel 16.11.2018 23:10

Слишком много проблем: (1) Вызов dollars() внутри dollars() приводит к бесконечной рекурсии (то же самое для cents). (2) Добавление значений в count почти везде, кроме тех, где это должно быть сделано. И, наверное, больше.

Michael Butscher 16.11.2018 23:15

@ user3757962 Совет: не используйте float для денежных значений. В этом случае вы должны изменить поле count на int и подсчитать количество центов (конвертировать доллары в центы и конвертировать их обратно, когда вам нужно)

Progman 16.11.2018 23:18

Слишком много проблем, трудно понять, с чего начать, но: 1) Метод add должен обновлять поля вашего класса. Это не так. 2) Не используйте float. Предлагаем вам использовать вместо этого 2 поля int, одно для значения dollars и одно для значения cents. 3) Условия "обеспечения" диапазона должны быть выполнены по методу add.

Andreas 16.11.2018 23:47
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
6
615
3

Ответы 3

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) сделаем неизменным. Это позволит избежать проблем с параллелизмом.

Хорошее решение, но слишком продвинутое, пропустите элементы неизменяемости / параллелизма и не выбрасывайте исключения

Joakim Danielson 17.11.2018 10:15
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 (как я вижу, у вас нет части центов).

P.S. Один трюк на будущее

Представьте, что вам нужны значения с плавающей запятой и вы поддерживаете все стандартные математические операции с ними, например +,-,/,*. Например. доллар и целое количество центов (как в вашем примере), и вы не можете (или не хотите) использовать операции с плавающей запятой. Что вы должны сделать?

Просто зарезервируйте два минимальных числа в целочисленном значении как дробную часть. Итак, возьмем пример для цены 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  

«Правило финансового программирования»: это не о финансовом программировании, это простое домашнее задание для новичков, поэтому, хотя это хорошее решение, оно не попадает в цель, потому что оно слишком продвинуто для тех, кто не знает разницы между методами и участниками.

Joakim Danielson 17.11.2018 10:10

Так или иначе. счетные деньги нельзя делать с поплавком!

oleg.cherednik 17.11.2018 10:14

Я, конечно, не возражаю с этим.

Joakim Danielson 17.11.2018 10:16

Здесь есть несколько полезных ответов. Я также понял, что неправильно понял задание (думал, что мне понадобится общая сумма денег вместо двух отдельных счетчиков для долларов и центов), и поэтому я сделал это сложнее, чем нужно.

Мое решение (которое проверено на работу с использованием предоставленного тестового класса) выглядит следующим образом:

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);

Ivan Lymar 18.11.2018 00:16

Я понимаю, о чем вы говорите. 444 цента просто добавят 1 доллар и вычтут 100 центов из 444 центов. Я немного упростил это и исправлю. Спасибо!

user3757962 18.11.2018 10:53

Другие вопросы по теме