0

ran0我从文本Numerical Recipes中获取了以下功能。我编写了自己的程序random2来调用ran0.

为什么这段代码会导致分段错误?谢谢你的时间。

FUNCTION ran0(idum)
  INTEGER idum,IA,IM,IQ,IR,MASK
  REAL ran0,AM
  PARAMETER (IA=16807,IM=2147483647,AM=1./IM,IQ=127773,IR=2836,MASK=123459876)
  INTEGER k
  idum=ieor(idum,MASK)
  k=idum/IQ
  idum=IA*(idum-k*IQ)-IR*k
  if (idum.lt.0) idum=idum+IM
  ran0=AM*idum
  idum=ieor(idum,MASK)
  return
END FUNCTION

PROGRAM random2
  IMPLICIT NONE
  REAL :: ran0
  PRINT *, ran0(6)
END PROGRAM
4

2 回答 2

5

您将常量 6.0 作为 IDUM 虚拟参数传递给您的函数。然后,您(尝试)使用 idum = ieor(...) 等行修改此参数。您实际上是在尝试修改常量。

6.0 的值现在已经固定了一段时间——足够长,以至于大多数程序员都希望在 5.0 和 7.0 之间找到它。请不要尝试更改它。

于 2013-03-05T22:33:39.773 回答
2

扩展 IanH 的答案,如果你用更现代的 Fortran 部分重写它:

module my_subs

contains

FUNCTION ran0(idum)
  INTEGER, intent(inout) :: idum
  INTEGER IA,IM,IQ,IR,MASK
  REAL ran0,AM
  PARAMETER (IA=16807,IM=2147483647,AM=1./IM,IQ=127773,IR=2836,MASK=123459876)
  INTEGER k
  idum=ieor(idum,MASK)
  k=idum/IQ
  idum=IA*(idum-k*IQ)-IR*k
  if (idum.lt.0) idum=idum+IM
  ran0=AM*idum
  idum=ieor(idum,MASK)
  return
END FUNCTION

end module my_subs

PROGRAM random2
  use my_subs
  IMPLICIT NONE
  !REAL :: ran0
  PRINT *, ran0(6)
END PROGRAM

将参数标识为具有intent(inout)属性的输入和输出并将子例程放在模块中并使用该模块允许编译器检查参数的一致性,编译器很可能会发现这个问题。例如,gfortran 输出:

PRINT *, ran0(6)
              1
Error: Non-variable expression in variable definition context (actual argument to INTENT = OUT/INOUT) at (1)
于 2013-03-06T00:13:59.760 回答