Discussion:
userland prng?
(too old to reply)
luser droog
2022-12-01 02:09:10 UTC
Permalink
I was trying to play with making a random number stream
and the numbers that work in C result in a very short period
when PostScript's auto-promoting mul is used.

Is there a way to do an integer multiply that truncates the
result to an integer ... in PS? Or some other way to generate
random numbers with the operators available in PostScript?


/rand_next 1 def

/fmod { 2 copy div truncate mul sub } def
/shuffle {
1103515245.0 mul 12345.0 add 16#100000000 fmod
} def

/zrand {
/rand_next rand_next shuffle def
rand_next cvi 16 bitshift
/rand_next rand_next shuffle def
rand_next cvi 16#FFFF and or
} def

10 { zrand = } repeat
rand_next =
/ =

/randstep { % rand_next -> [ rand_value { rand_next' randstep } ]
shuffle
dup cvi 16 bitshift exch
shuffle
dup cvi 16#FFFF and 3 2 roll or exch
/randstep cvx 2 array astore cvx 2 array astore
} def

1 randstep
10 {
aload pop exch =
exec
} repeat
==


$ gsnd rand.ps
GPL Ghostscript 9.55.0 (2021-09-27)
Copyright (C) 2021 Artifex Software, Inc. All rights reserved.
This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY:
see the file COPYING for details.
72320781647872
809041920
12345
232959026135040
809041920
12345
232959026135040
809041920
12345
232959026135040
0.0

72320781647872
809041920
12345
232959026135040
809041920
12345
232959026135040
809041920
12345
232959026135040
[809041920 {3.55467264e+09 randstep}]
GS> quit
luser droog
2022-12-01 02:13:02 UTC
Permalink
Post by luser droog
I was trying to play with making a random number stream
and the numbers that work in C result in a very short period
when PostScript's auto-promoting mul is used.
Is there a way to do an integer multiply that truncates the
result to an integer ... in PS? Or some other way to generate
random numbers with the operators available in PostScript?
Oops. Duh. If I mod them off to 16bits first then the mul shouldn't overflow.
luser droog
2022-12-01 02:18:52 UTC
Permalink
Post by luser droog
Post by luser droog
I was trying to play with making a random number stream
and the numbers that work in C result in a very short period
when PostScript's auto-promoting mul is used.
Is there a way to do an integer multiply that truncates the
result to an integer ... in PS? Or some other way to generate
random numbers with the operators available in PostScript?
Oops. Duh. If I mod them off to 16bits first then the mul shouldn't overflow.
Yeah, that's better.


/rand_next 1 def

/fmod { 2 copy div truncate mul sub } def
/shuffle {
16#10000 fmod cvi
1103515245 16#10000 fmod
mul
12345 add 16#100000000 fmod
} def

/zrand {
/rand_next rand_next shuffle def
rand_next cvi 16 bitshift
/rand_next rand_next shuffle def
rand_next cvi 16#FFFF and or
} def

20 { zrand = } repeat
rand_next =
/ =

/randstep { % rand_next -> [ rand_value { rand_next' randstep } ]
shuffle
dup cvi 16 bitshift exch
shuffle
dup cvi 16#FFFF and 3 2 roll or exch
/randstep cvx 2 array astore cvx 2 array astore
} def

1 randstep
20 {
aload pop exch =
exec
} repeat
==

$ gsnd rand.ps
GPL Ghostscript 9.55.0 (2021-09-27)
Copyright (C) 2021 Artifex Software, Inc. All rights reserved.
This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY:
see the file COPYING for details.
2124853504
59620810871936
71578490554560
67620669755968
6148069049408
66104907020736
19453098093376
36126488312000
62231291134528
43873720084416
13390047086912
3116543513408
6484905176320
15158436999296
59452392775680
53894596057984
73936343705536
56505076320576
46231573235392
2274453097664
7.3997e+08

2124853504
59620810871936
71578490554560
67620669755968
6148069049408
66104907020736
19453098093376
36126488312000
62231291134528
43873720084416
13390047086912
3116543513408
6484905176320
15158436999296
59452392775680
53894596057984
73936343705536
56505076320576
46231573235392
2274453097664
[4295470121696 {154043104.0 randstep}]
GS>

Loading...