Вычитание двойного дает неверный результат

Я пытаюсь получить десятичную часть от двойного, и это мой код для получения десятичной части

double  decimalvalue = 23423.1234-23423.0;
0.12340000000040163

Но после вычитания я ожидаю, что десятичное значение будет 0,1234, но я получаю 0,12340000000040163. Пожалуйста, помогите мне понять это поведение и есть ли обходной путь для него.


person Ahmed Masud    schedule 02.10.2012    source источник
comment
Существует бесконечное количество действительных значений, но только 64 бита в двойном.   -  person user7116    schedule 03.10.2012
comment
docs.oracle.com/cd/E19957-01/806- 3568/ncg_goldberg.html   -  person Mysticial    schedule 03.10.2012


Ответы (2)


Я предлагаю вам взглянуть на

Что должен знать каждый программист об арифметике с плавающей запятой

Википедия: IEEE 754

Существует конечное количество значений, которые вы можете указать в числе с плавающей запятой, но бесконечное количество чисел с плавающей запятой в представленном диапазоне.

Поэтому некоторые числа с плавающей запятой не могут быть точно представлены в любом типе данных с плавающей запятой/двойном стилем.

Типичный способ решения вашей конкретной проблемы — избежать прямого сравнения на равенство, а вместо этого выполнить тест на эпсилон: посмотреть, находятся ли ожидаемые и вычисленные значения в пределах некоторого небольшого числа (по сравнению с вычитаемыми значениями), называемого эпсилон< /em> друг друга.

Косвенно связана концепция Machine Epsilon, на которую стоит взглянуть для полного понимания.

person Eric J.    schedule 02.10.2012
comment
Эпсилон должен соответствовать величине сравниваемых чисел. - person user7116; 03.10.2012
comment
Для новичков почти равное значение намного хуже, чем ==. Узнайте, как работает с плавающей запятой; не пытайтесь скрыть это с помощью хаков, нарушающих транзитивность. - person Pete Becker; 03.10.2012

Это ошибка округления. В базе десять вы не можете точно представить 1/3 в заданном количестве цифр (скажем, 15). В базе 2 есть гораздо больше вещей, которые вы не можете представить, 0,1234 — одна из них. Точность зависит от масштаба, но это около 15 знаков после запятой для двойного числа. Я бы посоветовал взглянуть на http://en.wikipedia.org/wiki/IEEE_floating_point для подробнее о числах с плавающей запятой.

Если вы пытаетесь создать систему с основанием 10 (например, человеческий калькулятор) и вам нужны точные результаты, вы должны использовать BCD.

person CrazyCasta    schedule 02.10.2012
comment
... вы не можете представить с конечной точностью. - person user7116; 03.10.2012
comment
Лол, я как раз собирался изменить это сам :P - person CrazyCasta; 03.10.2012