fortran中的drand和drandm给出的数字超出[0,1]范围

问题描述 投票:0回答:2

这是下面的脚本,我使用隐式的无,因为我最终希望在具有更多变量的更大程序中实现它们。

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

第一个数字在范围内,但非常小,当我将其用于乘以其他值时,将给我零值。兰德有效,但我想使用drandm。我想获取0到1之间的随机数。如果我使用的函数不正确,请告诉我。

random fortran gfortran
2个回答
3
投票

您应使用固有的random_seedrandom_number在Fortran中生成随机数。内在的random_number将为您提供0到1之间的实数。

例如参见:


3
投票

@@ tim18回答了问题,但您可能还没完全明白为什么要得到这些结果。

我修改了程序以打印返回值的十六进制表示。使用ifort运行时,我得到:

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

IEEE双精度是8字节格式,并且drand / drandm返回8字节,但是您将它们声明为real(单精度),因此仅获得低4字节,而没有转换。由于这些类型之间的指数字段大小不同(8位和11位),因此将double的低4个字节解释为实数会得到错误的值。

现在看看如果我将drand和drandm声明为双精度会发生什么:

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

或者如果我返回列表导航:

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

更好?

也就是说,我完全同意那些建议改用RANDOM_NUMBER的人的观点。如果使用内在过程,您将不会看到这种问题。

© www.soinside.com 2019 - 2024. All rights reserved.