Небольшое число обрабатывается как ноль при добавлении в Фортран - PullRequest
1 голос
/ 26 марта 2019

Я пишу код для симуляции Монте-Карло в Фортране, но у меня много проблем из-за небольших чисел.

Самая большая проблема в том, что в моем коде позиции частиц не обновляются;инкриминированный код выглядит следующим образом

x=x+step*cos(p)*sin(t)

с step=0.001.При этом код не будет обновлять позицию, и я получаю бесконечный цикл, потому что частица никогда не выходит из области.Если я изменю свой код следующим образом:

 x=x+step

или

x=x+step*cos(t)

, проблем не будет.Таким образом, кажется, что произведение step*cos(t)*cos(p) (порядка 10 ** - 4) слишком мало и рассматривается как ноль.

x имеет порядок 10 ** 4.

Как мне решить эту проблему портативным способом?

Мой компилятор - самая последняя версия f95.

1 Ответ

2 голосов
/ 26 марта 2019

Ваша проблема, по сути, связана с другим вопросом . Тем не менее, полезно добавить некоторые комментарии к Фортрану.

Как и в этом другом вопросе, дискретный характер чисел с плавающей точкой означает, что существует точка, в которой одно число слишком мало, чтобы иметь значение при добавлении к другому. В случае этого вопроса:

if (1e4+1e-4==1e4) print *, "Oh?"
if (1d4+1d-4==1d4) print *, "Really?"
end

То есть вы можете использовать реалы двойной точности, и проблема исчезнет.

Какое наименьшее число можно добавить к 1e4, чтобы получить что-то отличное от 1e4 (или * 1d4)?

print *, 1e4 + SPACING(1e4), 1e4+SPACING(1e4)/2
print *, 1d4 + SPACING(1d4), 1d4+SPACING(1d4)/2
end

Этот интервал зависит от размера числа. Для больших чисел он большой, а около 1 - маленький.

print*, EPSILON(1e0), SPACING([(1e2**i,i=0,5)])
print*, EPSILON(1d0), SPACING([(1d2**i,i=0,5)])
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...