Два небольших числа вычитают, получают ноль в Фортране - PullRequest
0 голосов
/ 07 февраля 2019

Я пишу код на фортране, который работает с высокой точностью.Здесь я пытаюсь использовать ISO_FORTRAN_ENV для достижения этой цели.Я узнаю, что если вычесть два небольших числа, ответ, который я получу, будет нулевымНо если я добавлю их, все будет в порядке.

Вот моя программа:

program test

  USE ISO_FORTRAN_ENV, ONLY : REAL32

  IMPLICIT NONE
  REAL(REAL32), PARAMETER :: RE_L=-1.7499576837060936950743114606, &
                            RE_R=-1.7499576837060933110499019727
  REAL(REAL32) :: A 

  A=(RE_R)-(RE_L)
  PRINT 20, A
  20 FORMAT(f50.40)


end program test

Результат, который я получил, составляет 0,00000000000000000000000000000.И я не знаю почему.

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

Вы сталкиваетесь с значащими цифрами Single Precision в литералах и в диапазоне REAL32.

Возвращаетесь к REAL64, добавляете двойной спецификатор для литералов 1.7499576837060933110499019727d+0

prompt$ gfortran toosmallorg.f90
prompt$ ./a.out
        0.0000000000000004440892098500626161694527

Даже с литералами REAL64 d вы получаете только 16 цифр после десятичной точки, и отображаемый результат неверен.В REAL32 распознаются только 7 цифр после десятичной дроби (в настройках по умолчанию эта машина Fedora имеет gfortran 7.3).REAL128 может дать достаточно места для маневра с литералами.

Справедливое предупреждение;Не эксперт по Фортрану или допускаемой числовой точности

0 голосов
/ 07 февраля 2019

Это длинная история, вы можете найти в Google некоторые ключевые работы, такие как «Что должен знать каждый программист об арифметике с плавающей точкой», появятся некоторые очень хорошие релевантные страницы.

Короче говоря, floatФормат точек, с плавающей точкой или двойной, может представлять число только с определенной точностью.Алгоритм должен быть тщательно разработан в некоторых случаях, чтобы получить разумную точность, например, минимальная точка с плавающей точкой x, которая составляет (1,0 + x) -1,0! = 0,0, определяется как FLT_EPSILON, его значение на удивление больше, чем вы могли ожидать.

...