[Fortran] Rounding up Random Numbers

Click For Summary
SUMMARY

The forum discussion focuses on generating an array of random binary numbers (0s and 1s) using Fortran 95. The user initially encounters issues with the NINT function, which incorrectly assigns values to the integer array due to improper indexing. The solution involves using a loop to correctly round each element of the random number array, ensuring all elements of the integer array are populated. The final code produces a 10x10 matrix of random 0s and 1s, demonstrating effective use of the random number generator and NINT function.

PREREQUISITES
  • Understanding of Fortran 95 programming language
  • Familiarity with random number generation in Fortran
  • Knowledge of the NINT function for rounding in Fortran
  • Basic array manipulation in Fortran
NEXT STEPS
  • Explore advanced random number generation techniques in Fortran
  • Learn about debugging techniques in Fortran to prevent segmentation faults
  • Investigate formatting output in Fortran using different format edit descriptors
  • Study matrix operations in Fortran for more complex data manipulations
USEFUL FOR

This discussion is beneficial for Fortran developers, programmers working with random number generation, and anyone interested in improving their skills in array manipulation and debugging in Fortran 95.

Lukejambo
Messages
13
Reaction score
0
Hi,

So I'm writing a programme in Fortran95 atm and I want to produce an array of 1s and 0s.

I've used a random number and random seed generator to produce 10 numbers between 0 and 1 and I want to use a NINT statement to round these random numbers to 0 or 1.

However when I try this the rounded numbers are very large which I know shouldn't happen...

Any help will be much appreciated.
 
Technology news on Phys.org
Perhaps you could show your work, so we can critique it.
 
Thanks for the quick reply Dave! Here is the code:

program random
implicit none
integer :: n
real :: a(10)
integer :: i(10)

n=10
call random_seed()
call random_number(a)

write(6,*) (a(n),n=1,10)
write(6,*) ''

i(n) = NINT(a(n))

write(6,*) (i(n),n=1,10)

end program random
 
And the output?

If you would put in some debugging lines, of particular interest would be the values of a(n) just before the NINT function.
 
  • Like
Likes   Reactions: Lukejambo
Lukejambo said:
Thanks for the quick reply Dave! Here is the code:

program random
implicit none
integer :: n
real :: a(10)
integer :: i(10)

n=10
call random_seed()
call random_number(a)

write(6,*) (a(n),n=1,10)
write(6,*) ''

i(n) = NINT(a(n))

write(6,*) (i(n),n=1,10)

end program random
I think it's this line: i(n) = NINT(a(n)). I believe that all this is doing is setting i(10) to the rounded value in a(10). i(1), i(2), ..., i(9) will have garbage values.
If you want all 10 elements of your i array to have values, do this:
Code:
do n = 1, 10
   i(n) = NINT(a(n))
end do
 
  • Like
Likes   Reactions: Lukejambo
Mark44 said:
I think it's this line: i(n) = NINT(a(n)). I believe that all this is doing is setting i(10) to the rounded value in a(10). i(1), i(2), ..., i(9) will have garbage values.
It's even worse than that, as n has a value of 11 after the loop in write(6,*) (a(n),n=1,10). The original code could produce a segmentation fault.

Mark44 said:
If you want all 10 elements of your i array to have values, do this:
Code:
do n = 1, 10
   i(n) = NINT(a(n))
end do
In Fortran 95, the loop can be implicit:
Code:
   i = NINT(a)
 
  • Like
Likes   Reactions: Lukejambo
Thanks very much for your help, I've managed to produce a matrix of ones and zeroes which are all randomly placed.
 
It would be awesome if you posted your result, so that others may learn.
 
Here is the code:! This programme produces a 10x10 matrix of 0's and 1's using the random number and random seed function.

program randomex
implicit none
integer :: n
real :: a(100)
integer :: i(100)
open(unit=20, file='randomex')n=100
call random_seed()
call random_number(a)

! Below writes the matrix of random numbers, all between 0 and 1.

write(6,'(10f5.3)') (a(n),n=1,100)
write(20,'(10f5.3)') (a(n),n=1,100)
write(6,*) ''

! Rounding these random numbers up/down.

i = NINT(a)

! Writing the matrix to screen.

write(6,'(10i2)') (i(n),n=1,100)
write(20,'(10i2)') (i(n),n=1,100)
write(6,*) ''end program randomex
 
  • #10
And the output:0.7180.3280.1310.5310.1930.5790.1660.4610.7620.613
0.7380.1280.4020.4000.2200.9330.0800.7640.9990.505
0.6310.6970.8230.9630.6980.4480.9360.3010.9390.489
0.9860.4930.3490.4180.1700.8120.8390.0900.4720.117
0.4600.9490.5750.1400.0460.8190.8350.4690.0500.043
0.6670.3730.0860.7360.2130.4890.0480.2610.5900.725
0.3230.7440.3710.1320.5550.6510.4830.4160.3020.064
0.8560.3270.6190.4030.6840.0930.0150.6130.3940.412
0.1760.7080.7980.8920.9990.4480.9090.7350.3680.634
0.0250.6520.9440.8540.3770.2880.5530.1050.0340.424

1 0 0 1 0 1 0 0 1 1
1 0 0 0 0 1 0 1 1 1
1 1 1 1 1 0 1 0 1 0
1 0 0 0 0 1 1 0 0 0
0 1 1 0 0 1 1 0 0 0
1 0 0 1 0 0 0 0 1 1
0 1 0 0 1 1 0 0 0 0
1 0 1 0 1 0 0 1 0 0
0 1 1 1 1 0 1 1 0 1
0 1 1 1 0 0 1 0 0 0
 
  • #11
@Lukejambo, do you still have a question? Your output suggests that your program is working as intended, although the output of the unrounded numbers is harder to read than it should be. For the real numbers, you are printing them using this write statement
Code:
write(6,'(10i2)') (i(n),n=1,100)
Here you are using a format edit descriptor of 10i2 to print them in fields of 10 integers (i2), using a width of two columns for each. Since each number takes up more than two columns, the compiler overrides your I2 format descriptor.

A better choice would be to print them using a real format descriptor such as F10.8 for each number, followed by a space, X.

I think this would work, but I don't currently have a Fortran compiler to test it on.
Code:
write(6, '5(F10.2, X)') (i(n),n=1,100)
 
  • #12
Mark44 said:
For the real numbers, you are printing them using this write statement
Code:
write(6,'(10i2)') (i(n),n=1,100)

You got the wrong line there, he is using
Fortran:
write(6,'(10f5.3)') (a(n),n=1,100)

But you are correct that it would be better to add a space
Fortran:
write(6,'(10(f5.3,x))') (a(n),n=1,100)
 
  • #13
Right you are @DrClaude, I was thinking the last two write statements created the output he posted -- the first for the raw numbers, and the second for the rounded ints.
 

Similar threads

  • · Replies 21 ·
Replies
21
Views
8K
  • · Replies 6 ·
Replies
6
Views
2K
  • · Replies 3 ·
Replies
3
Views
3K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 1 ·
Replies
1
Views
3K
Replies
25
Views
4K
Replies
3
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K