Как справиться с тем, что большинство десятичных дробей не могут быть точно представлены в двоичном виде? - PullRequest
5 голосов
/ 02 ноября 2009

Итак, мы знаем, что дробные части, такие как 0,1, не могут быть точно представлены в двоичной базе, что вызывает точные проблемы (такие как упомянуто здесь: Форматирование удваивается для вывода в C # ).

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

так что же нам делать?

Ответы [ 7 ]

7 голосов
/ 02 ноября 2009

Для всестороннего изучения проблем, связанных с выполнением вычислений с плавающей точкой, см. Эту статью:

Что должен знать каждый компьютерщик об арифметике с плавающей точкой http://docs.sun.com/source/806-3568/ncg_goldberg.html

4 голосов
/ 02 ноября 2009

О, что нам делать с тем фактом, что большинство десятичных дробей нельзя представить в двоичном формате? или в этом отношении, что двоичные дроби не могут быть представлены в десятичном виде?

или, даже, что бесконечность (фактически неисчисляемая бесконечность) действительных чисел во всех базах не может быть точно представлена ​​ни в одной компьютеризованной системе?

ничего! Чтобы вспомнить старый клише, Вы можете подойти достаточно близко для правительственной работы ... На самом деле, вы можете подойти достаточно близко для любой работы ... Нет предела степени точности, которую может генерировать компьютер, она просто не может быть бесконечной , (что требуется для того, чтобы схема представления чисел могла представлять каждое возможное действительное число)

Видите ли, для каждой схемы представления чисел, которую вы можете спроектировать, на любом компьютере она может представлять только конечное число различных различных действительных чисел с точностью 100,00%. И между каждой соседней парой этих чисел (тех, которые могут быть представлены с точностью 100%) всегда будет бесконечность других чисел, которые он не может представить с точностью 100%.

3 голосов
/ 02 ноября 2009

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

Если вы пишете программное обеспечение для управления ядерным реактором или для моделирования первой миллиардной доли вселенной после большого взрыва (мой друг на самом деле это сделал), вам потребуется гораздо более высокая точность, чем при расчете продаж налог (то, чем я зарабатываю на жизнь).

Например, в мире финансов существуют особые требования к точности, прямо или косвенно. В некоторых налоговых юрисдикциях США ставки налога устанавливаются до 5 цифр после запятой. Ваша схема округления должна учитывать такую ​​точность. Когда большая часть Западной Европы перешла на евро, был очень специфический подход к округлению, который был прописан в законе. В течение этого переходного периода было необходимо округлить в точности так, как требуется.

Знайте правила своего домена и проверьте, соответствует ли ваша схема округления этим правилам.

3 голосов
/ 02 ноября 2009

так что же нам делать?

Мы просто продолжаем дышать. Это действительно не структурная проблема. У нас ограниченная точность, но обычно более чем достаточно. Вам просто нужно помнить форматировать / округлять при представлении чисел.

Проблема в следующем фрагменте кода связана с WriteLine(), а не с вычислениями:

double x = 6.9 - 10 * 0.69;
Console.WriteLine("x = {0}", x);

Если у вас есть конкретная проблема, отправьте ее. Обычно есть способы предотвратить потерю точности. Если вам действительно нужно> = 30 десятичных цифр, вам нужна специальная библиотека.

2 голосов
/ 02 ноября 2009

Я думаю, что все намекают: Инвертирование разреженной матрицы? «Для этого есть приложение» и т. Д.

Численное вычисление - одна хорошо выпоротая лошадь. Если у вас есть проблема, она, вероятно, была поставлена ​​на пастбище до 1970 года или даже намного раньше, перенесена из библиотеки в библиотеку или из фрагмента в фрагмент.

1 голос
/ 04 июля 2010

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

Некоторые из математических методов do support decimal: Abs, Ceiling, Floor, Max, Min, Round, Sign и Truncate. Общим для этих функций является то, что они возвращают точные результаты. Это согласуется с целью decimal: сделать точную арифметику с числами от 10 до 10 *.

Функции trig и Exp / Log / Pow возвращают приблизительные ответы, так какой смысл иметь перегрузки для "точного" арифметического типа?

1 голос
/ 02 ноября 2009

Вы можете сместить десятичную точку так, чтобы числа были целыми, затем выполнить 64-разрядную целочисленную арифметику, а затем сдвинуть ее обратно. Тогда вам придется беспокоиться только о проблемах переполнения.

...