Fortran Coder

查看: 14750|回复: 4
打印 上一主题 下一主题

[讨论] Fortran中所生成的随机数范围

[复制链接]

1963

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1357 元
贡献
574 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

楼主
发表于 2018-7-23 17:18:32 | 显示全部楼层
不是这么计算的。正确的计算方法是:

落入 [0.0,0.1) 概率为 0.1
落入 [0.1,0.2) 概率为 0.1
落入 [0.2,0.3) 概率为 0.1
...
落入 [0.9,1.0) 概率为 0.1
(总和为 1),平均每10次可以得到一次。

在第一种可能中,
落入 [0.00,0.01) 概率为 0.01
落入 [0.01,0.02) 概率为 0.01
落入 [0.02,0.03) 概率为 0.01
...
落入 [0.09,0.10) 概率为 0.01
(总和为0.1),平均每100次可以得到一次

所以,
落入 [0,1.0e-38) 的概率为 1/1.0e-38,平均 10e38 次可以得到一次 0
而不是 2147483648

PS:我这里用十进制来计算,实际应该按二进制来计算。也就是落入 [0,0.5) , [0.5,1.0)  的概率,以及 [0,0.25) [0.25,0.5) [0.5,0.75) [0.75,1.0) 的概率,这样算下去。算法不同,结果一致。

你确定你计算了 10e38 次吗?
按24小时来计算,你的运算能力要达到每 1.1574073E+33 次,才可能在理想情况下得到1次0


1963

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1357 元
贡献
574 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

沙发
发表于 2018-7-23 17:32:30 | 显示全部楼层
你可以用以下代码测试一下概率。

[Fortran] 纯文本查看 复制代码
Program Main
  real :: a
  integer(8) :: i = 0_8 , j
  integer(8) :: ddc(38) = 0
  call RANDOM_SEED()
  do
    call RANDOM_NUMBER(a)
    j = int(-log10(a)) + 1
    ddc(j) = ddc(j) + 1
    i = i + 1_8
    if( mod(i,100000000_8) == 0_8 ) then
      write(*,'("Total:",g0)') i
      write(*,'(*(5i16,/))') ddc
      write(*,'("check:",g0)') sum(ddc)
    end if
  end do  
  read(*,*) 
End Program Main


这个代码用来统计,N次取随机数的结果,其结果各数量级的个数,也就是 0.1以内的个数,0.01以内的个数,0.001以内的个数...
当 N 足够大时,个数之间的比例大约是
0.9 , 0.09 , 0.009 .... 加起来约等于 1

如图:


也就是说,我算了 20亿次,才得到一个 e-10 次方数量级的数。
你要想得到 0 ,你需要大约10次得到 e-38 次方数量级的数的机会。
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-5-3 15:21

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表