Чтобы получить лучшую десятичную точность, я решил использовать "длинный двойной" в моем коде C++. Но даже следующий код:
long double a=5;
long double b=0.54645;
long double c=a*b;
printf("%Lf\n", c);
генерирует -0.00000 на моем компьютере. Я думаю, что это ошибка компилятора, как указывают ответы.
Мотивация заключалась в том, что я занимаюсь большим количеством парных разрядов, умножая их, а затем добавляя результаты. При добавлении мне нужно, чтобы окончательный ответ был меньше 1е-6 от правильного ответа. Но использование двойников позволяет мне ошибочный ответ из-за проблем с точками. По неправильному ответу я имею в виду более 1е-6. Итак, я решил использовать длинные парные.
Но еще один факт привлек мое внимание, а именно: когда я использовал длинные удваивания и запускал свою программу на онлайн-платформе IDE (ideone.com), она все еще округляется, как двойная, и дает мне менее точный ответ. Что нужно сделать, чтобы этого избежать?
Ваша программа работает правильно в моей системе (после того, как я удаляю нерелевантный треск); выход:
5.000000
0.546450
2.732250
Если я изменю форматы %Lf
на %f
(что неверно), я получаю 0.00000
.
Я думаю, вы используете MinGW, реализацию C для Windows, которая использует компилятор gcc и библиотеку времени выполнения Microsoft. (Если вы не используете MinGW, остальная часть этого ответа неверна.)
У MinGW есть известная ошибка: она не обрабатывает long double
последовательности. gcc рассматривает long double
более широкий тип с большим диапазоном и точностью, чем double
; Библиотека времени выполнения Microsoft, если я правильно помню, рассматривает ее как тип с таким же размером, диапазоном и точностью как double
.
Любое представление вполне допустимо, но объединение двух в одной реализации создает такую ошибку. Это не ошибка в gcc или в реализации Microsoft; это ошибка в том, как MinGW объединил их.
Вы можете выполнять вычисления с использованием long double
и получать согласованные результаты, если вы не вызываете каких-либо функций библиотеки. Но если вы попытаетесь напечатать long double
с помощью Microsoft printf
вы получите непоследовательные результаты.
Предположительно та же проблема относится к функциям в <math.h>
.
Если вы используете MinGW, скорее всего, просто избегайте использования long double
и соглашайтесь на меньший диапазон и точность double
(в любом случае это тот же диапазон и точность, которые вы получите с long double
в чистой реализации Microsoft),
Кстати, ваша самодостаточная программа намного больше, чем она должна быть; подавляющее большинство из них совершенно не имеет отношения к проблеме, о которой вы просите. И вызовы freopen
препятствуют появлению вывода. У вас есть комментарий:
//Remember to remove freopen
но вы оставили вызовы на месте.
Здесь небольшая версия:
#include <cstdio>
int main()
{
long double a=5;
long double b=0.54645;
long double c=a*b;
printf("%Lf\n", a);
printf("%Lf\n", b);
printf("%Lf\n", c);
return 0;
}
std::cout
?