2014-11-10 5 views
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' дать вам? – Evert

+0

Это дает мне -6.00905e-083, что, как вы можете видеть, также неверно. –

+0

Что вы получаете, если вы «печатаете» все значения (т. Е. 'A',' b' и 'c')? –

ответ

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, потому что мне нравится делать IO через текстовые файлы. Результат должен быть таким же. Мой комментарий есть, когда мне нужно отправить код кому-то другому (кто не может использовать freopen). Ваша меньшая версия также не работает на моем компьютере. Я думаю, что это проблема MinGw. Спасибо за ответ. –

+0

Вы не смогли ответить на его вопрос: «Когда я использовал длинные удваивания и запускал свою программу на онлайн-платформе IDE (ideone.com), она все еще округляется, как двойной, и дает мне менее точный ответ. чтобы избежать этого? ». –

+0

@ParamjitSingh: Для меня это имело значение для меня, потому что ваша программа не выдавала видимого результата, когда я компилировал и запускал ее в своей системе. Мне не приходило в голову искать файл 'Output.txt'. Перенаправление stdio в файл просто омрачает проблему. –

Смежные вопросы