2013-10-03 4 views
-3

Есть ли у кого-нибудь идея, где моя проблема с выпуском?Weird Java Outputs - Запуск VM на Mac lion с Eclipse

Я написал программу на Java и запустил ее на виртуальной машине на Mac lion с Eclipse. Вместо того, чтобы получать 1.41, я получил 1.4100000000000001 на своей машине.

Example: 
Enter the number of quarter: 4 
Enter the number of dimes: 3 
Enter the number of nickels: 2 
Enter the number of pennies: 1 

Total $1.4100000000000001 

Example: 
Enter the number of quarter: 3 
Enter the number of dimes: 2 
Enter the number of nickels: 1 
Enter the number of pennies: 6 

Total $1.06 

Example: 
Enter the number of quarter: 5 
Enter the number of dimes: 7 
Enter the number of nickels: 4 
Enter the number of pennies: 4 

Total $2.1900000000000004 

Иногда кажется, что выходы правильные, в то время как другие проблемы имеют проблемы.

Код:

import java.util.*; 

public class CountChange 
{ 
    public static void main(String[]args) 
    { 
     Scanner inputScanner = new Scanner(System.in); 
     System.out.print("Enter the number of quarters: "); 
     int quarters = inputScanner.nextInt(); 
     System.out.print("Enter the number of dimes: "); 
     int dimes = inputScanner.nextInt(); 
     System.out.print("Enter the number of nickles: "); 
     int nickles = inputScanner.nextInt(); 
     System.out.print("Enter the number of pennies: "); 
     int pennies = inputScanner.nextInt(); 
     inputScanner.close(); 

     double total =0.00; 
     total = quarters * 0.25 + dimes * 0.1 + nickles * 0.05 + pennies * 0.01; 

     System.out.println("Total $" + total); 
     System.out.print("Thank you"); 
    } 
} 
+1

http://floating-point-gui.de/ –

+0

Если вы используете числа с плавающей запятой, вам нужно округлить результаты. Попробуйте 'System.out.printf (« $%.2f% n ", value);' –

ответ

2

Ваша проблема связана с тем, как с плавающей точкой (ставить легко, float/double связанные расчеты) имеют место. Числа с плавающей запятой являются приблизительным репертуаром (если вас интересует теория, стандарт равен IEEE754). Здесь вы получаете именно это, приблизительное представление.

Поскольку вы обрабатываете деньги, которые идут только на центы (вы не можете иметь 0,0001 $ в валюте), я предлагаю представить значения с int (или long или любыми целыми типами) значениями в виде центов. Затем разделите на 100 при отображении результата.

+0

Некоторые из моих цен безопасности указаны в единицах $ .0001. Программисты должны остерегаться допущений. –

+0

OP обрабатывает * реальную * валюту (квартал, десять центов и т. Д.). такая 0,0001 $ монета. –

+0

Программисты должны остерегаться допущений. –

1

Вы испытали неточность представления чисел с плавающей запятой как double s. Число 0,1 не может быть представлено точно в двоичном формате, поэтому, когда вы говорите 0.1 на Java, вы получаете максимально возможное приближение к 0.1. То же самое относится к 0.05 и 0.01.

Есть несколько вещей, которые вы можете сделать:

  • Отложите арифметику с плавающей точкой для как можно дольше.

Пример:

total = quarters * 25 + dimes * 10 + nickles * 5 + pennies; 
total /= 100.0; 
  • Используйте DecimalFormat, чтобы отрезать дисплей после двух знаков после запятой.

Пример:

DecimalFormat df = new DecimalFormat("0.00"); 
System.out.println("Total $" + df.format(total)); 

Ни один из этих способов получает вокруг основного вопроса - неточное представление числа на double. Специально для суммы денег, не используйте double. Вместо этого вы можете использовать BigDecimal, точность которого произвольна.

0

Я согласен с объяснениями, почему вы столкнулись с этой проблемой. Мое рекомендуемое решение для такого рода ситуаций на Java - это использование BigDecimal. Это точно те вычисления, которые вы ожидаете быть точными для коротких десятичных дробей. Для неточных вычислений он предлагает хороший выбор методов округления.

Фактически, он выполняет целочисленную арифметику с коэффициентом масштабирования, но автоматизирует хранение и управление шкалой.

+0

Большое спасибо за все входы. – user2844217

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