tags:

views:

185

answers:

6

Hello ! I've noticed, that standard rand() function gives different results on Windows and Linux. Ofcourse I've used the same seed number (1234). Here are several first results:

WIN: 4068 213 12761 8758

LIN: 479142414 465566339 961126155 1057886067

My application requires that both platforms produce identical output. What are my options? Is there any good replacement for rand() that meets my requirement ?

thanks

PS. I used MSVC 2008 on Windows7, and gcc 4.1.2 on CentOS 5.5

+3  A: 

You won't get the same results due to the different implementation of the functions on either platform.

Femaref
+14  A: 

Boost has a wide range of RNGs, presumably with reproducible behaviour across platforms.

Marcelo Cantos
The Boost PRNG's all have references to the algorithm they implement and the paramters chosen. So, not only will the behavior be reproducible, it will also be mathematically defined (i.e. there is an absolute standard for correctness)
MSalters
+5  A: 
Oli Charlesworth
Why “not recommended”? A LCG is a trivial one-liner, and the Wikipedia article offers a list of commonly-used constants that produce more or less good behaviour (on par with the C standard library implementations).
Konrad Rudolph
Not recommended because the correctness of the implementation is hard to test and any errors aren't immediately apparent but may cause issues much later during app execution. Also, why reinvent the wheel?
Eamon Nerbonne
@Eamon: “why reinvent the wheel?” It’s a frackin’ **one-liner**. Downloading the Boost header (although this would be the first solution I’d recommend, too) is guaranteed to be more work. And in general I’d agree about correctness. But once again: it’s a one-liner. Which I copied from Wikipedia. What’s there to get wrong?
Konrad Rudolph
@Konrad: You may need better properties than the LCG can offer.
Oli Charlesworth
WHile I agree with @Konrad that reasonable LCG constants are available and the implementation of one is trivial, I *still* wouldn't use it except in the most speed or space constrained circumstances because they suffer quality issues even when drawing (x,y) pairs.
dmckee
@Oli, @dmckee: I would never usually use an LCG – but the OP already does so I suspect that its properties are sufficient.
Konrad Rudolph
It is not recommended because among all the uses of random numbers, some have quite serious implications, for example when they are used for cryptography. Those uses need not-obvious-at-all mathematical properties and even experts on the subject get it wrong after years of research, making it a really non-trivial problem. In the end it's generally just simpler to avoid doing your own generator altogether. This is why it's generally not recommended, unless you know for sure you're using it for something that doesn't matter.
Jean
@Konrad: an LCG may be a one-liner, but it doesn't work very well and other RNG's are trivial to use... *if* you don't reinvent the wheel. And *even if* it's just a one-liner, to a maintenance programmer the "just use boost" approach will be easier to read and more trustworthy.
Eamon Nerbonne
@Konrad: "the OP already does [use an LCG]" - not on Linux. I don't know about Windows.
Mike Seymour
@Mike: for MSVC, it’s an LCG. For Linux – [it depends](http://www.mscs.dal.ca/~selinger/random/). (I suppose you meant glibc?)
Konrad Rudolph
A: 

You may try srand(int), which generates random number based on seed (input)

-- Cheers

Koteswara sarma
True, but the results will only be the same if the underlying algorithm and parameters are also the same.
GregS
+2  A: 

I think you will even find different linux versions returning different values, as well as different windows versions returning different values.

You could unify your random generator by using the glibc one, for example.

Another option for you is writing your own function BUT do that ONLY if you are 100% sure you don't need to use your random for cryptographic use or any other use that requires the thing to have unpredictability or uniformness or otherwise randomish properties.

Jean
+3  A: 

If you’re happy with the standard rand implementation and only require reproduceability, you can easily write your own linear congruential generator (adapting the C interface, probably not a good choice! – rather use a class instead):

namespace myown {

static int state;

void srand(int seed) {
    state = seed;
}

int rand() {
    int const a = 1103515245;
    int const c = 12345;
    state = a * state + c;
    return (state >> 16) & 0x7FFF;
}

}

This uses constants (ANSI C: Watcom) from the Wikipedia article.

That said, I’d rather go with a read-made implementation from Boost, as proposed by others.

Konrad Rudolph
+1 for the correct answer to the question (the OP wants reproduce-ability, not a good RNG). Just remember to use a good RNG once you've finished testing >;-)
smirkingman