2012-04-26 2 views
0

Так что я сейчас читаю книгу об изучении Java, и программа, изложенная в книге, дает мне некоторые проблемы. В частности, когда я запускаю программу для вычисления суммы долларов и изменений, которые у меня должны быть с 9.87, я получаю изменение от того, что получаю, как если бы я набрал 9.86. Однако, когда я печатаю 9.86, я получаю правильное количество изменений. Насколько я знаю, это происходит только с некоторыми суммами, которые заканчиваются на 0,87, например 8,87, хотя он работает на 6,87 штрафа. Это книга введение в java-программирование 8-е издание, и так как это была книга, написанная профессионалом, я смущен относительно того, что может быть ошибкой. Я попытался запустить его в cmd и eclipse, и оба, похоже, показывают ошибку.Ошибка программы Logic

Pastebin Ссылка:

http://pastebin.com/CVssSUYp

+0

Читайте о конверсиях с плавающей точкой в ​​int. Простые усечения (округляются вниз). Вы хотите конвертировать «раунд к ближайшему». Т.е.: 'int ОсталосьAmount = (int) ((сумма + 0,005) * 100);' –

ответ

5

Я почти уверен, что вас укусил плохое понимание того, как числа с плавающей точкой работы. Вы не можете больше представлять 0,1 точно в двоичном формате больше, чем 1/3 в десятичном значении. Затем, кроме того, номера с плавающей запятой IEEE не могут иметь более 17 цифр точности для парных.

Это не ошибка на Java или ваш код.

Деньги - это классический пример того, что не должно быть представлено десятичными числами.

Написать класс Деньги с целыми долларами и центами и использовать его, когда вы узнаете достаточно Java:

public class Money { 
    private final int dollars; 
    private final int cents; 
    private final Currency currency; 

    public Money(int dollars, int cents, Currency curr) { 
     if (dollars < 0) throw new IllegalArgumentException("dollars cannot be negative"); 
     if (cents < 0) throw new IllegalArgumentException("cents cannot be negative"); 
     if (curr == null) throw new IllegalArgumentException("currency cannot be null"); 
     this.dollars = dollars; 
     this.cents = cents; 
     this.currency = curr; 
    } 
    // more methods here. 
} 
+0

Хорошо, спасибо, что очистили это. Чтобы уточнить, когда я сказал «очерчен», я имел в виду, что это был точный код из книги. Я думаю, он не вдавался в подробности о том, почему число, подобное 9.87, не будет работать, потому что он не хотел путать или, возможно, он упомянет об этом позже, в любом случае, спасибо вам большое. – Andrew

0

duffymo прав. 9.87 x 100 в float может быть 986.999999999 ... который преобразуется в 986 при возврате в целое число.

Возможно, вы можете использовать Math.round() перед приведением типов (int), чтобы округлить поплавок до ближайшего целого числа.

import java.lang.Math; 
... 
int remainingAmount = (int)(Math.round(amount * 100)); 
... 

производит правильный вывод:

Your amount 9.87 consists of 
     9 dollars 
     3 quarters 
     1 dimes 
     0 nickels 
     2 pennies 

Привет,

Мэнни

0

Попробуйте установить сумму 9,87, а затем умножением его с 100:

double amount=9.87; 
System.out.println(amount*100); 

После что, попробуйте печать то же самое, но бросил его в целом:

double amount=9.87; 
System.out.println((int)amount*100); 

Кастинг в целое только удаляет десятичный в конце (как горячие лижут сказал в комментарии) и потому, что вы не можете представить числа с плавающей точкой в ​​точности (как duffymo сказал в ответе), вы получите 986 вместо 987, как вы и ожидали.

Смежные вопросы