TRand
Overview
Trand
implements triggerable random number generator.
Every time a trigger is received, it produces a new random
number in a given range.
Tangled Files
trand.c
and trand.h
. SK_TRAND_PRIV
will expose
the struct contents for sk_trand
.
#ifndef SK_TRAND_H
#define SK_TRAND_H
#ifndef SKFLT
#define SKFLT float
#endif
#ifdef SK_TRAND_PRIV
<<structs>>
#endif
<<typedefs>>
<<funcdefs>>
#endif
#define SK_TRAND_PRIV
#include "trand.h"
<<funcs>>
Initialization and Struct
Initialize trand with sk_trand_init
. It will need
an initial seed value for the internal RNG.
void sk_trand_init(sk_trand *tr, unsigned long seed);
void sk_trand_init(sk_trand *tr, unsigned long seed)
{
<<init>>
}
The struct for trand is sk_trand
.
typedef struct sk_trand sk_trand;
The sk_trand
struct contains the RNG state, min/max
ranges, and a random value that was generated last.
For optimization, a scale
variable is used to scale the
RNG value within range. A changed
variable is also used
to signal if min or max have changed, and will trigger
the scale
value to update (this is a version of
parameter caching, but using one flag
to monitor the state of two variables).
struct sk_trand {
unsigned long rng;
SKFLT min;
SKFLT max;
SKFLT val;
SKFLT scale;
int changed;
};
TRand will be initialized to output values between 0 and 1, with it's internal seed set to the one provided by the init function.
Note: val
will be set to be 0. This means that trand
will return 0 until the first trigger.
tr->rng = seed;
tr->val = 0;
tr->changed = 0;
tr->min = 0;
tr->max = 1;
tr->scale = 1.0 / 2147483648L;
Parameters
TRand takes has two parameters: min and max. These set the
range of the random numbers, and can be set with
sk_trand_min
and sk_trand_max
.
void sk_trand_min(sk_trand *tr, SKFLT min);
void sk_trand_max(sk_trand *tr, SKFLT max);
void sk_trand_min(sk_trand *tr, SKFLT min)
{
if (tr->min != min) {
tr->min = min;
tr->changed = 1;
}
}
void sk_trand_max(sk_trand *tr, SKFLT max)
{
if (tr->max != max) {
tr->max = max;
tr->changed = 1;
}
}
Compute
Computed with sk_trand_compute
.
SKFLT sk_trand_tick(sk_trand *tr, SKFLT trig);
If a trigger happens, update the random number. If the parameters change, update the scaling.
SKFLT sk_trand_tick(sk_trand *tr, SKFLT trig)
{
if (trig != 0) {
if (tr->changed) {
tr->changed = 0;
tr->scale = 1.0 / 2147483648L;
tr->scale *= (tr->max - tr->min);
}
tr->val = tr->min + (tr->rng * tr->scale);
tr->rng = (1103515245 * tr->rng + 12345) % 2147483648;
}
return tr->val;
}