Различная точность в C ++ и Fortran

Для проекта, над которым я работаю, я написал в C ++ очень простую функцию:

Fne(x) = 0.124*x*xпроблема в том, когда я вычисляю значение функции

за x = 3.8938458092314270 и с Фортраном 77, и с языками C ++ я получил разное преимущество.

Для Фортрана я получил Fne(x) = 1.8800923323458316 и для C ++ я получил Fne(x) = 1.8800923630725743, Для обоих языков функция Fne кодируется для значений двойной точности и возвращает также значения двойной точности.

Код C ++:

double FNe(double X) {
double FNe_out;
FNe_out = 0.124*pow(X,2.0);
return FNe_out;
}

Код Фортрана:

  real*8 function FNe(X)
implicit real*8 (a-h,o-z)
FNe = 0.124*X*X
return
end

Не могли бы вы помочь мне выяснить, откуда эта разница?

1

Решение

Одним из источников различий является обработка по умолчанию C ++ и Fortran литеральных констант, таких как ваша 0.124, По умолчанию Fortran будет рассматривать это как число с плавающей запятой одинарной точности (практически на любой комбинации компьютера и компилятора, которую вы, вероятно, будете использовать), в то время как C ++ будет рассматривать его как число f-p двойной точности.

В Фортране вы можете указать kind числа f-p (или любой другой внутренней числовой константы в этом отношении и отсутствие каких-либо опций компилятора для изменения наиболее вероятного поведения по умолчанию) путем суффикса вид-селектор как это

0.124_8

Попробуйте, посмотрите, что получится.

О, и пока я пишу, почему вы пишете на Фортране, как это было в 1977 году? И всем остальным экспертам Фортрана поблизости, да, я знаю, что *8 а также _8 это не лучшая практика, но у меня нет времени, чтобы подробно остановиться на этом.

2

Другие решения

Как отметило High Performance Mark, проблема точности литералов по умолчанию. С помощью

double xx = 3.8938458092314270;
std::cout << std::setprecision(16);
std::cout << " (float) * x*x: " << 0.124f*xx*xx << std::endl;
std::cout << "(double) * x*x: " << 0.124*xx*xx << std::endl;

Мы получаем

 (float) * x*x: 1.880092332345832
(double) * x*x: 1.880092363072574

это та же самая разница, которую вы заметили.

0

По вопросам рекламы [email protected]