Skip to content

Commit 30c2b24

Browse files
committed
COMMON: rand() replacment using PCG
1 parent 036a356 commit 30c2b24

File tree

7 files changed

+50
-6
lines changed

7 files changed

+50
-6
lines changed

samples/distro-examples/tests/all.bas

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ print "RIGHT:" + RIGHT (s,2)
198198
print "RIGHTOF:" + RIGHTOF (s1, s2)
199199
print "RIGHTOFLAST:" + RIGHTOFLAST (s1, s2)
200200
print "RINSTR:" + RINSTR (2, s1, s2)
201-
print "RND:" + RND
201+
print "RND:" + iff(RND>=0 && RND<=1.0,1,0)
202202
print "ROUND:" + ROUND (x,22)
203203
print "RTRIM:" + RTRIM (s)
204204
print "RUN:" '+ RUN cmdstr

samples/distro-examples/tests/output/all.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ RIGHT:gs
183183
RIGHTOF:
184184
RIGHTOFLAST:
185185
RINSTR:0
186-
RND:0.75898406142369
186+
RND:1
187187
ROUND:12.3
188188
RTRIM:catsanddogs
189189
RUN:

src/common/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ libsb_common_a_SOURCES = \
5454
device.c device.h \
5555
screen.c \
5656
system.c \
57+
random.c \
5758
eval.c \
5859
extlib.c extlib.h \
5960
file.c \

src/common/blib.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,18 +2051,18 @@ void cmd_restore() {
20512051
* RANDOMIZE [num]
20522052
*/
20532053
void cmd_randomize() {
2054-
long seed;
2054+
var_int_t seed;
20552055

20562056
byte code = code_peek();
20572057
switch (code) {
20582058
case kwTYPE_LINE:
20592059
case kwTYPE_EOC:
2060-
srand(clock());
2060+
pcg32_srand(clock());
20612061
break;
20622062
default:
20632063
seed = par_getint();
20642064
if (!prog_error) {
2065-
srand(seed);
2065+
pcg32_srand(seed);
20662066
}
20672067
};
20682068
}

src/common/blib_func.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ var_num_t cmd_math0(long funcCode) {
480480
}
481481
break;
482482
case kwRND:
483-
r = ((var_num_t) rand()) / (RAND_MAX + 1.0);
483+
r = pcg32_rand();
484484
break;
485485
default:
486486
rt_raise("Unsupported built-in function call %ld", funcCode);

src/common/random.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// This file is part of SmallBASIC
2+
//
3+
// lowlevel device (OS) I/O
4+
//
5+
// This program is distributed under the terms of the GPL v2.0 or later
6+
// Download the GNU Public License (GPL) from www.gnu.org
7+
//
8+
// Copyright(C) 2000 Nicholas Christopoulos
9+
10+
#include "config.h"
11+
12+
#include "common/sys.h"
13+
#include <stdint.h>
14+
#include <limits.h>
15+
16+
// see:
17+
// https://en.wikipedia.org/wiki/Permuted_congruential_generator
18+
// https://www.pcg-random.org/download.html
19+
20+
static uint64_t state = 0x4d595df4d0f33173;
21+
static uint64_t multiplier = 6364136223846793005u;
22+
static uint64_t increment = 1442695040888963407u;
23+
24+
static uint32_t rotr32(uint32_t x, unsigned r) {
25+
return x >> r | x << (-r & 31);
26+
}
27+
28+
var_num_t pcg32_rand() {
29+
uint64_t x = state;
30+
unsigned count = (unsigned)(x >> 59);
31+
state = x * multiplier + increment;
32+
x ^= x >> 18;
33+
int32_t r = rotr32((uint32_t)(x >> 27), count);
34+
return ((var_num_t)abs(r)) / (INT_MAX + 1.0);
35+
}
36+
37+
void pcg32_srand(var_int_t seed) {
38+
state = seed + increment;
39+
pcg32_rand();
40+
}

src/common/sys.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ typedef uint32_t bcip_t;
120120
#include "include/var.h"
121121
#include "common/str.h"
122122

123+
var_num_t pcg32_rand(void);
124+
void pcg32_srand(var_int_t seed);
125+
123126
#if !defined(O_BINARY)
124127
#define O_BINARY 0
125128
#endif

0 commit comments

Comments
 (0)