### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: How make Random Numbers (from,to)  (Read 11873 times)

#### VTwin

• Hero Member
• Posts: 979
• Former Turbo Pascal 3 user
##### Re: How make Random Numbers (from,to)
« Reply #15 on: July 15, 2018, 03:03:59 pm »
Can you give me an example that does that, I mean different results?: usually my code is tested on Linux (x86_64 and ARM), OSX and on Windows 64. It is supposed to give the same results on all platforms.
So if it does not (given the same randseed) there is a bug and I need to fix it.

It was a while back, but it seemed to me that NaN values were treated differently on different platforms. I develop on Mac, and then would run into problems on Win. I was trying to use NaN as a test value, and got inconsistent results. A user needed to enter explicit missing values as 'NaN' (or old school punch card '999'). For my own purposes I defined:

Code: Pascal  [Select][+][-]
1. const
2.   NAIOFloat : double  = -1.7e+308;   // explicit missing value, i/o = 'NaN'
3.   NAFloat   : double  = -1.6e+308;   // missing value, i/o = ''
4.
5. { IsNA
6.   'Is Not Available', returns true if number is not valid. }
7. function  IsNA(r: double): boolean;
8. begin
9.   result := (r = NAFloat) or (r = NAIOFloat);
10. end;
11.
12. { IsNAIO
13.   'Is Not Available', returns true if number is explicitly not valid. Normally
14.   user entered NaN or 999. }
15. function  IsNAIO(r: double): boolean;
16. begin
17.   result := (r = NAIOFloat);
18. end;
19.
20. { IsNum
21.   Uses NAFloat, a very large magnitude negative double whose magnitude
22.   is bigger than mMaxFloat. Use NAFloat to initialize doubles, and IsFloat
23.   to test for a real value. Use -mMaxFloat for smallest double. }
24. function IsNum(r: double): boolean;
25. begin
26.   result := (r > NAFloat);
27. end;
28.
29. etc.
30.

as work arounds. It seemed odd to me, as this was using a virtual machine, so the processor was identical. I will look into it further and try to give you a clear example.
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.0
macOS 10.13.6: Lazarus 2.0.12 (64 bit Cocoa)
Ubuntu 18.04.3: Lazarus 2.0.12 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.0.12 (64 bit on VBox)

• Hero Member
• Posts: 10753
##### Re: How make Random Numbers (from,to)
« Reply #16 on: July 15, 2018, 03:34:30 pm »
Well, the pseudo randoms I described are all based on bit-patterns (and Unsigned). Avoiding NaN (or Infinity) is therefor not represented in any Pascal (or C, C++)  code for those PRNG's I have seen.
If it is important to you to avoid both NaN and Infinity, you could mask out the possibility by "and \$EF<As many FF's - 1 as needed for the size>.
That WILL reduce your randomness to sqr("size of" -1). E.g. given 16 bit integer randomness is 15 bit. You will loose entropy. As long as you realize that, it should not be a practical problem.
The HWRNG's can also generate NaN or Infinity for the same reason.

So basically you can avoid both by a mask of the size of a native unsigned type and loose 1 bit precision.
I do not know of any - guaranteed - other way, but this algorithm is cross-platform.

« Last Edit: July 15, 2018, 03:51:31 pm by Thaddy »

#### VTwin

• Hero Member
• Posts: 979
• Former Turbo Pascal 3 user
##### Re: How make Random Numbers (from,to)
« Reply #17 on: July 15, 2018, 04:54:06 pm »
@vtwin
Yes I know most of them.
I have a hard copy of numerical recipes (The Pascal one!!)  And a first edition of "TAOCP" which is rather a rare find.
Note most of the PRNG's I published are invented beyond the '80's and - on a whole - with a better distribution than NR.
(Test them with bigcrush! as per my wiki entry.) I can add some of the old school stuff, though: the newer ones are more like discoveries than science...
Also note that HRNG's are much older. <but you probably knew that  >

I seem to have acquired four hard copies of NR, in C, Pascal and Fortran over the years, as well as several more recent electronic copies. It is too bad the licensing is not more flexible, I recently purged NR from my code in preparation to open source.  A first edition of TAOCP is a nice find, I'd pick that up if I found a copy.

It is excellent to have more up to date algorithms available. I appreciate you pointing that out, I guess I should check to see if I am using older versions. I don't have a good understanding of RNGs, or follow the literature, so depend on experts such as yourself. I just need one sometimes, so like to have good code available. If you decide to add a few old school ones, that could be a nice addition. Also perhaps note which ones are modern improvements, so people like me don't continue to use dusty old code from the 80s.

And, no, I could not have told you that HRNGs are much older, interesting though.
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.0
macOS 10.13.6: Lazarus 2.0.12 (64 bit Cocoa)
Ubuntu 18.04.3: Lazarus 2.0.12 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.0.12 (64 bit on VBox)

#### VTwin

• Hero Member
• Posts: 979
• Former Turbo Pascal 3 user
##### Re: How make Random Numbers (from,to)
« Reply #18 on: July 15, 2018, 05:39:58 pm »
Well, the pseudo randoms I described are all based on bit-patterns (and Unsigned). Avoiding NaN (or Infinity) is therefor not represented in any Pascal (or C, C++)  code for those PRNG's I have seen.
If it is important to you to avoid both NaN and Infinity, you could mask out the possibility by "and \$EF<As many FF's - 1 as needed for the size>.
That WILL reduce your randomness to sqr("size of" -1). E.g. given 16 bit integer randomness is 15 bit. You will loose entropy. As long as you realize that, it should not be a practical problem.
The HWRNG's can also generate NaN or Infinity for the same reason.

So basically you can avoid both by a mask of the size of a native unsigned type and loose 1 bit precision.
I do not know of any - guaranteed - other way, but this algorithm is cross-platform.

Ok, thanks, I did not know that NaN and Infinity could be generated. So, for example, if I am generating random numbers from a Gaussian distribution, I should be checking? I assume the Math functions IsInfinite and IsNan should work to detect them instead of masking?

I do not specifically remember a problem with RNGs and NaNs. Maybe I was doing it incorrectly, but I seemed to have encountered cross-platform differences in assigning and/or detecting NaNs. I'd have to try to recreate the issue.

EDIT: Thanks, very interesting. It does make sense if it is based on bit patterns, and that masking will be quicker.
« Last Edit: July 15, 2018, 05:51:22 pm by VTwin »
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.0
macOS 10.13.6: Lazarus 2.0.12 (64 bit Cocoa)
Ubuntu 18.04.3: Lazarus 2.0.12 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.0.12 (64 bit on VBox)

• Hero Member
• Posts: 10753
##### Re: How make Random Numbers (from,to)
« Reply #19 on: July 15, 2018, 06:05:30 pm »
EDIT: Thanks, very interesting. It does make sense if it is based on bit patterns, and that masking will be quicker.
Note the values itself are always valid. Performing calculations with them can give problems.

#### VTwin

• Hero Member
• Posts: 979
• Former Turbo Pascal 3 user
##### Re: How make Random Numbers (from,to)
« Reply #20 on: July 16, 2018, 12:27:05 am »
EDIT: Thanks, very interesting. It does make sense if it is based on bit patterns, and that masking will be quicker.
Note the values itself are always valid. Performing calculations with them can give problems.

Makes sense!

For anyone who is curious, I found an interesting article discussing IEEE NaN and Infinity:

http://www.efg2.com/Lab/Mathematics/NaN.htm

“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.0
macOS 10.13.6: Lazarus 2.0.12 (64 bit Cocoa)
Ubuntu 18.04.3: Lazarus 2.0.12 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.0.12 (64 bit on VBox)