Возможный дубликат:
Потеря точности с двойным C ++
Я пытаюсь выполнить некоторые вычисления с использованием C ++, но он не работает должным образом, например, когда я запускаю очень простой код, такой как код ниже,
int main()
{
double a = 93548387.09678;
double b = a * a;
printf("result is: %f \n", b);
}
это показывает результат как: 8751300728408995.000000
вместо: 8751300728408994.7970863684
Как я могу исправить эту проблему?
Вы видите 16 значащих цифр, что примерно столько же, сколько вы можете получить от типичного double
: У вас есть 53 бита для мантиссы и 253 около 1016 (точнее, журнал10(253) = 15.955).
Другими словами, два числа являются то же самое, округленное до 16 значащих цифр.
Учитывая отзывы в комментариях, возможно, я должен подчеркнуть, что даже переменная a
на самом деле не имеет значения 93548387.09678
, Будет ближайший представима значение этого числа, но это не то же самое. Там действительно нет такой вещи, как «точный результат»; все зависит только от точности.
Если вам нужны точные вычисления, вам нужно использовать другой тип данных: либо десятичные типы с плавающей запятой (но они также имеют фиксированную, конечную точность), либо библиотеку десятичных чисел с плавающей запятой произвольной точности, либо рациональную рациональную точность библиотека
Если вам действительно нужно больше точности, вы должны написать свой собственный класс для этого или вы можете попытаться найти его.
Числа с плавающей запятой двойной точности имеют только 15-17 десятичных цифр точности. Увидеть «Формат с плавающей запятой двойной точности»:
Это дает точность от 15 до 17 значащих десятичных цифр.
Видеть это вопрос если вам нужно больше точности, чем то, что double
обеспечивает.
Как сказано многими людьми выше, double
имеют недостаточную точность для ваших требований. Они также являются наиболее точными в стандартах C и C ++, поэтому вам придется использовать стороннюю библиотеку.
Хорошее решение будет использовать GNU MP — библиотека множественной точности GNU. Синтаксис не будет красивым, но это естественный эффект от того, что доступные литералы C ++ слишком малы.
Вам нужны более значимые цифры, чем double
обеспечивает.
Заглянуть в библиотека арифметики произвольной точности если вам нужно больше точности.
В зависимости от вашей реализации, long double
может предложить более правильные значащие цифры, чем double
, Таким образом, вы могли бы даже получить некоторые десятичные числа правильно (но вряд ли вы получите точный ответ при любой обычной реализации, смотри пример).
Если вам нужна еще большая точность (или «бесконечная» точность), вы должны использовать арифметическую библиотеку произвольной точности, такую как GMP.
К сожалению, вы не можете. Double сохраняет правильную точность только для 16 значащих цифр, что именно там, где вас обрезают.