2

I am learning Fortran and I would like to make a little game to practice the input. The objective is to find the good number, who is a random one. I made a code to generate the number but my problem is that, the result is a random number, but it's always the same. For example, when I execute the code 3 times, it print 21 the three times.

Here is my code :

program find_good_number
    integer :: random_number
    integer :: seed
    seed = 123456789
    call srand(seed)
    random_number = int(rand(0)*100)
    print*, random_number
end program find_good_number

Can you help me please ? Thanks

Napyt
  • 43
  • 6
  • 2
    Note the subroutine random_number is the standard Fortran random number generator, stand is an extension which may not be supported by all compilers – Ian Bush Aug 21 '21 at 19:26

1 Answers1

5

Using GNU Fortran 10.3 with the standard intrinsics, and asking the Fortran runtime library to peek the seed, it seems that every invocation of the program does result in a different serie of random numbers. So that would be OK for the sort of application you have in mind.

Using this code:

Program TestRandom1

  implicit none

  integer :: randomSeedSize
  integer :: count = 3
  integer :: k     = 0
  real    :: rx    = 0.0

  call random_seed(size = randomSeedSize)
  write (*,'(a,i4)')   'size of random seed (in integers): ',  &
                       randomSeedSize

  call random_seed()  ! use system-provided seed

  do k = 1, count
      call random_number(rx)
      write (*, '(a,f10.8)') 'rx = ', rx
  end do

End Program TestRandom1

Context:

$ 
$ uname -s -m -r
Linux 5.13.9-100.fc33.x86_64 x86_64
$ 
$ gfortran --version
GNU Fortran (GCC) 10.3.1 20210422 (Red Hat 10.3.1-1)
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ 

Testing:

$ 
$ random1.x
size of random seed (in integers):    8
rx = 0.23642105
rx = 0.39820033
rx = 0.62709534
$ 
$ random1.x
size of random seed (in integers):    8
rx = 0.84118658
rx = 0.45977014
rx = 0.09513164
$ 
$ random1.x
size of random seed (in integers):    8
rx = 0.33584720
rx = 0.86550051
rx = 0.26546007
$ 

A seed size of 8*32 = 256 bits looks consistent with the xoshiro256 algorithm mentioned here in the GNU Fortran documentation.

jpmarinier
  • 4,427
  • 1
  • 10
  • 23
  • 2
    This was a behaviour change in [GCC 7](https://stackoverflow.com/a/31922538/3157076). – francescalus Aug 21 '21 at 22:42
  • Just be aware that the Fortran standard does not define the behavior of a call to RANDOM_SEED without arguments. Some compilers randomize the seed, some don't. F2018 has RANDOM_INIT for this purpose. – Steve Lionel Aug 22 '21 at 01:02
  • @SteveLionel - You're right, and I am afraid this means that, if we need to ensure on every platform that the random seed will dutifully change from run to run , we have to use some resource external to Fortran. For example, call a C routine and have it sample /dev/urandom. Or have some Python script fill a small text file with 8 random integers. This is an unfortunate situation :-( – jpmarinier Aug 22 '21 at 17:16
  • 4
    First, you have to call RANDOM_SEED with the SIZE argument to determine how large the seed array is, then allocate an array to that size - it isn't always 8, fill it and then call RANDOM_SEED again with the PUT argument. Often routines such as SYSTEM_CLOCK and DATE_AND_TIME are used to get differing values. Once your compiler supports RANDOM_INIT, this becomes much easier. You could write your own version of RANDOM_INIT that hides this from the main program. – Steve Lionel Aug 22 '21 at 19:10