[Fortran] Rounding up Random Numbers

Click For Summary

Discussion Overview

The discussion revolves around generating an array of random numbers in Fortran95, specifically focusing on rounding these numbers to 0 or 1 using the NINT function. Participants explore issues related to code implementation, debugging, and output formatting.

Discussion Character

  • Technical explanation
  • Debugging
  • Mathematical reasoning

Main Points Raised

  • One participant describes their attempt to generate an array of 1s and 0s using random numbers and the NINT function, noting unexpected large values in the output.
  • Another participant suggests showing the code for critique and emphasizes the importance of debugging lines to inspect values before applying the NINT function.
  • A participant points out that the original code only sets the last element of the integer array and proposes a loop to correctly assign values to all elements.
  • Concerns are raised about the potential for segmentation faults due to incorrect indexing in the original code.
  • After implementing suggested changes, one participant reports success in generating a matrix of random 0s and 1s.
  • Another participant encourages sharing results for the benefit of others.
  • Formatting issues are discussed regarding the output of real numbers, with suggestions for improving readability using different format descriptors in the write statements.
  • Clarifications are made regarding the correct lines of code responsible for output formatting, with a focus on ensuring proper spacing and alignment in the printed results.

Areas of Agreement / Disagreement

Participants generally agree on the need for proper indexing and formatting in the code. However, there are differing opinions on the best approach to output formatting, with multiple suggestions provided without a clear consensus on which is superior.

Contextual Notes

Limitations include potential segmentation faults due to incorrect array indexing and unresolved issues with output formatting that may affect readability.

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