Типы с плавающей запятой с фиксированной точностью, те, которые изначально поддерживаются модулем с плавающей запятой вашего ЦП (float
, double
, real
), не оптимальны для любых вычислений, которые требуют много цифр точности, например, в примереВы дали.
Проблема в том, что эти типы с плавающей запятой имеют конечное число цифр точности (фактически двоичные цифры), что ограничивает длину числа, которое может быть представлено таким типом данных.Тип float
имеет ограничение приблизительно в 7 десятичных цифр (например, 3.141593);тип double
ограничен 14 (например, 3.1415926535898);и тип real
имеет аналогичное ограничение (чуть больше, чем double
).
Добавление чрезвычайно малых чисел к значению с плавающей запятой приведет к потере этих цифр.Посмотрите, что произойдет, когда мы сложим вместе следующие два значения с плавающей запятой:
float a = 1.234567f, b = 0.0000000001234567
float c = a + b;
writefln("a = %f b = %f c = %f", a, b, c);
Оба a
и b
являются действительными значениями с плавающей запятой и сохраняют приблизительно 7 цифр прецизионной единицы в отдельности.Но при добавлении сохраняются только первые 7 цифр, потому что они возвращаются обратно в число с плавающей точкой:
1.2345670001234567 => 1.234567|0001234567 => 1.234567
^^^^^^^^^^^
sent to the bit bucket
Таким образом, c
в конечном итоге равняется a
, поскольку более точные цифры от добавленияa
и b
получают удар.
Вот еще одно объяснение концепции , вероятно, намного лучше, чем у меня.
Ответ на эту проблемуявляется арифметикой произвольной точности.К сожалению, поддержка арифметики произвольной точности не в аппаратном обеспечении процессора;следовательно, это не (обычно) в вашем языке программирования.Однако есть много библиотек, которые поддерживают типы с плавающей точкой произвольной точности и математические вычисления, которые вы хотите выполнить для них.См. этот вопрос для некоторых предложений.Вероятно, вы не найдете сегодня для этой цели каких-либо специфичных для D библиотек, но существует множество библиотек C (GMP, MPFR и т. Д.), Которые должны быть достаточно простыми для использования в изоляции, и даже более того, если вы сможете найтиD привязки для одного из них.