Ошибка десятичной точки

0

Чтобы получить лучшую десятичную точность, я решил использовать "длинный двойной" в моем коде 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), она все еще округляется, как двойная, и дает мне менее точный ответ. Что нужно сделать, чтобы этого избежать?

  • 0
    Что дает std::cout ?
  • 0
    Это дает мне -6.00905e-083, что, как вы видите, тоже не правильно.
Показать ещё 28 комментариев
Теги:
double
long-integer

1 ответ

4
Лучший ответ

Ваша программа работает правильно в моей системе (после того, как я удаляю нерелевантный треск); выход:

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;
}
  • 0
    Я знаю, что многие вещи здесь не имеют значения, но я не понимаю, как их включают в себя и макросы. На моем компьютере я использую freopen, потому что мне нравится выполнять ввод-вывод через текстовые файлы. Результат должен быть таким же. Мой комментарий там, когда я должен отправить код кому-то еще (кто не может использовать freopen). Ваша уменьшенная версия также не работает на моем компьютере. Я думаю, что это проблема MinGw. Спасибо за ответ.
  • 0
    Вы не смогли ответить на его вопрос: «Когда я использовал длинные двойные пары и запускаю свою программу в онлайн-среде IDE (ideone.com), она все еще округляется, как двойная, и дает мне менее точный ответ. Что нужно сделать, чтобы избежать этого?
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню