дранд и драндм в фортране дают числа вне диапазона [0,1] - PullRequest
0 голосов
/ 10 января 2020

Вот мой сценарий ниже, я использую неявный none, потому что я хотел бы в конечном итоге реализовать их в более крупной программе с большим количеством переменных.

program testdrandm
implicit none
real, external :: drand, drandm, rand

        print *, 'drand', drand(0), drand(0)
        print *, 'drandm', drandm(0), drandm(0)
        print *, 'rand', rand(0), rand(0)
end program testdrandm

вот мой вывод:

 drand  4.3290930E-39  -686.1465
 drandm -8.9381798E+10  1.7946890E+19
 rand  0.9679557      0.1896898

Первое число находится в пределах диапазона, но чрезвычайно мало и даст мне нулевые значения, когда я использую его для умножения других значений. Рэнд работает, но я хотел бы использовать драндм. Я хотел бы получить случайные числа от 0 до 1. Пожалуйста, дайте мне знать, если я использую эту функцию неправильно.

Ответы [ 2 ]

3 голосов
/ 11 января 2020

@ tim18 коснулся ответа, но вы, возможно, не поняли точно, ПОЧЕМУ вы получили эти результаты.

Я изменил программу, чтобы вывести шестнадцатеричное представление возвращаемых значений. При запуске с использованием ifort я получаю:

drand 00000000002F23C0 00000000C42B8960 drandm 00000000D1A67C90 000000005F791029 rand 000000003F77CBF2 000000003E423E09

Двойная точность IEEE - это 8-байтовый формат, а drand / drandm возвращает 8 байт, но вы объявили их как real ( одинарная точность), поэтому вы получаете только 4 младших байта, а НЕ преобразование. Поскольку размер поля экспоненты у этих типов различен (8 битов против 11 битов), интерпретация младших 4 байтов двойного числа как действительного приведет к неправильным значениям.

Теперь посмотрим, что произойдет, если я объявляют drand и drandm с двойной точностью:

drand 3EF791E0002F23C0 3FB5C4AFC42B8960 drandm 3FE33E47D1A67C90 3FEC88145F791029 rand 000000003F77CBF2 000000003E423E09

или, если I go, обратно к списку:

 drand  2.247793601009899E-005  8.503244914348818E-002
 drandm  0.601352605317418       0.891611277075303
 rand  0.9679557      0.1896898

Лучше?

Тем не менее, я полностью согласен с теми, кто предлагает вместо этого использовать RANDOM_NUMBER. Вы не видели бы такого рода проблем, если бы использовали процедуру intrinsi c.

3 голосов
/ 10 января 2020

Вы должны использовать intrinsi c random_seed и random_number для генерации случайных чисел в Фортране. Intrinsi c random_number даст вам реальные цифры от 0 до 1.

См. Например:

...