Мои Конспекты
Главная | Обратная связь

...

Автомобили
Астрономия
Биология
География
Дом и сад
Другие языки
Другое
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Металлургия
Механика
Образование
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Туризм
Физика
Философия
Финансы
Химия
Черчение
Экология
Экономика
Электроника

Если требуются точные ответы, избегайте использования типов float и doubIe





Помощь в ✍️ написании работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

 

Типы float и double в первую очередь предназначены для научных и инженер­ных расчетов. Oни реализуют бинарную арифметику с плавающей точкой (binary f!oating-point arithmetic), которая была тщательно выстроена с тем, чтобы быстро по­лучать правильное приближение для широкого диапазона значений. Однако эти типы не дают точного результата, и в ряде случаев их нельзя использовать. Типыfloat и double не подходят для денежных расчетов, поскольку с их помощью невозможно представить число 0.1 (или любую другую отрицательную степень числа десять).

Например, у вас в кармане лежит $1.03, и вы тратите 42 цента. Сколько денег у вас осталось? Приведем фрагмент наивной программы, которая пытается ответить на этот вопрос:

 

Sуstеm.оut.рrintln(1.0З - .42);

 

Как ни печально, программа выводит 0.6100000000000001. И это не единствен­ный случай. Предположим, что у вас в кармане есть доллар, и вы покупаете девять прокладок для крана по десять центов за каждую. Какую сдачу вы получите?

 

System.out.println(1.00 - 9*.10);

 

Если верить этому фрагменту программы, то вы получите $0.09999999999999995. Может быть, проблему можно решить, округлив результаты перед печатью? К сожа­лению, это срабатывает не всегда. Например, у вас в кармане есть доллар, и вы видите

 

 

 

полку, где выстроены в ряд вкусные конфеты за 10, 20, 30 центов и так далее вплоть до доллара. Вы покупаете по одной конфете каждого вида, начиная с той, что стоит 10 центов, и так далее, пока у вас еще есть возможность взять следующую конфету. Сколько конфет вы купите и сколько получите сдачи? Решим эту задачу следующим образом:

 

// Ошибка: использование плавающей точки для денежных расчетов!

public static void main(String[] args) {

double funds = 1.00;

int itemsBought = 0;

for (double price = .10; funds >= price; price += .10) {

funds -= price;

itemsBought++; }

System.out.println(itemsBought + " items bought."); System.out.println("Change: $" + funds); }

Запустив программу, вы выясните, что можете позволить себе .три конфеты и у вас останется еще $0.39999999999999999. Но это неправильный ответ! Пра­вильный путь решения задачи заключается в применении для денежных расчетов типов BigDecimal, int или long. Представ м простое преобразование предыдущей программы, которое позволяет использовать тип BigDecimal вместо double:

public static void main(String[] args) {

final BigDecimal TEN_CENTS = new BigDecimal( ".10”);

int itemsBought = 0;

BigDecimal funds = new BigDecimal("1.00");

for (BigDecimal price = TEN_CENTS;

funds.compareTo(price) >= 0;

price = price.add(TEN_CENTS)) {

itemsBought++;

funds = funds.subtract(price); }

System.out.print1n(itemsBought + " items bought."); System.out.print1n("Money left over: $" + funds); }

Запустив исправленную программу, вы обнаружите, что можете позволить себе четыре конфеты и у вас останется $0.00. Это верный ответ. Однако тип BigDecimal имеет два недостатка: он не столь удобен и медленнее, чем простой арифметический тип. Последнее можно считать несущественным, если вы решаете единственную маленькую задачу, а вот неудобство может раздражать.

 

 

Вместо BigDecimal можно использовать int или long (в зависимости от обраба­тываемых величин) и самостоятельно отслеживать положение десятичной точки. В нашем при мере расчеты лучше производить не в долларах, а в центах. Продемон­стрируем этот подход:

 

public static void main(String[] args) {

int itemsBought = 0;

int funds = 100;

for (int price = 10; funds >= price; price += 10) {

itemsBought++;

funds - = price;

}

System.out.println(itemsBought + " items bought.");

System.out.println("Money left over: " + funds + " cents"); }

 

Подведем итоги. Для вычислений, требующих точного результата, не используйте типы float и double. Если вы хотите, чтобы система сама отслеживала положение десятичной точки, и вас не пугают неудобства, связанные с отказом от простого типа, используйте BigDecimal. Применение этого класса имеет еще то преимущество, что он дает вам полный контроль над округлением: для любой операции, завершающейся округлением, предоставляется на выбор восемь режимов округления. Это пригодится, если вы будете выполнять экономические расчеты с жестко заданным алгоритмом округления. Если для вас важна производительность, вас не пугает необходимость самостоятельно отслеживать положение десятичной точки, а обрабатываемые значения не слишком велики, используйте тип int или long. Если значения содержат не более девяти десятичных цифр, можете применить тип int. Если в значении не больше восемнадцати десятичных цифр, используйте тип long. Если же в значении более восемнадцати цифр, вам придется работать с BigDecimal.

Доверь свою работу ✍️ кандидату наук!
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой



Поиск по сайту:







©2015-2020 mykonspekts.ru Все права принадлежат авторам размещенных материалов.