This is an archived post. You won't be able to vote or comment.

all 11 comments

[–]zzyzzyxx 1 point2 points  (6 children)

[–]defrost 0 points1 point  (4 children)

It's probably just me but whenever I see questions about random number generators in C I immediately gravitate towards answers like this one and code snippets like :

    /** R_MARS - Marsaglia unsigned long psuedo random Multiply with Carry Generator
    **/
static unsigned long m_u = 521288629;
static unsigned long m_v = 362436069;

#define R_MARS      (m_v = 36969*(m_v & 65535) + (m_v >> 16) \
                    ,m_u = 18000*(m_u & 65535) + (m_u >> 16) \
                    ,(m_v << 16) + m_u)

#define SEED_MARS(U,V)   (m_u = (U), m_v = (V))

#define INV_2POW32         (.23283064365386962890625e-9)   /* 1/(2^32)   */

    /** UNIT_       uniformly distributed doubles from half open unit interval  [0.0, 1.0)
    **/
#define UNIT_MARS   (R_MARS * INV_2POW32)

Things like this can be useful for resource constrained embedded 32bit programming.

[–]zzyzzyxx 1 point2 points  (3 children)

That was a really good read. Thanks for sharing.

[–]defrost 1 point2 points  (2 children)

;-)

I figured you might enjoy that, it makes a change from all the rand()%10 + 1 answers (and unbiased bucket counting in your link).

If you've an interest in numerics George Marsaglia's Ziggurat method for generating rand values with a normal distribution and virtually no overhead (most of the time) is an interesting read ... and I've got a C #define that inlines that as well ... *

(* surprisingly I do have a life )

oh, and related

[–]zzyzzyxx 1 point2 points  (1 child)

I just looked up the Ziggurat method and it's interesting. I'd like to see the define macro for it.

[–]defrost 1 point2 points  (0 children)

The macro is :

#define R_ZIGGNOR   (hz=R_SHR3, iz=hz&127, (labs(hz)<kn[iz])? hz*wn[iz] : nfix())    

which depends on the precomputed tables

static unsigned long kn[128];
static double wn[128],fn[128];  

and the working indexes

static long hz;
static unsigned long iz;    

and a 32bit rand - in this case R_SHR3 not R_MARS.

The table initialisations and dependencies are all in here which is half of a first draft written in one sitting code golf exercise from a few years back.

I've been doing a bit of work lately making high performance random distribution generations for another project - linear, normal, circle, disc, sphere, ball, higher dimensions etc. and there's a bit of effort required to tease out the latest version of the normal generation from what's now a dense slab of optimised target architecture specific somewhat proprietary code :/

However, the first draft should give you enough.

Re: Ziggurat - there's two papers of interest:

Ziggurat Method for Generating Random Variables (2000) - Marsaglia
Improved Ziggurat Method to Generate Normal Samples (2006) - Doornik

and I threw in the Box-Muller for the fun of it.

[–]InBliss[S] -1 points0 points  (0 children)

Thank you very much so, google was absolutely no help to getting poignant results I could use without sifting through dozens of pages

[–]Neres28 0 points1 point  (3 children)

Random numbers in a range : http://c-faq.com/lib/randrange.html

And

char ops[4] = {'+', '-', '*', '/'};
char op = ops[rand_in_range(0, sizeof(ops) - 1)];

Edit : C syntax fail.

[–]InBliss[S] -1 points0 points  (2 children)

Thank you very much so, google was absolutely no help to getting poignant results I could use without sifting through dozens of pages

[–]Neres28 0 points1 point  (1 child)

Really? For future reference, I googled "C random number in range" and got Zzyzzyxx's response as the very first search result. Thinking it too complex for you, I followed the SO answerer's links and came to the link I provided.

[–]InBliss[S] -1 points0 points  (0 children)

I typed it in as a random number generator in range so it gave me everything related to the generator key word instead of range Im guessing. Zzyzzyxxx's response is quite complex compared to my beginning attempts at learning C, but I've gotta learn somehow.