3

I wanted to generate a random integer, so I used C++ rand(void) and srand(int) functions:

int main(){
     srand(1);
     cout << rand() << endl;
     return 0;
}

OK, it suits my needs. Each time I execute it I get same result, which I like it!
But there is a problem. When I executed it on my computer I got 16807 as output. But when I executed it on another machine, I got 1804289383.

I know that rand() and srand(int) have a simple implementation similar to this:

static unsigned long int next = 1;

int rand(void) // RAND_MAX assumed to be 32767
{
    next = next * 1103515245 + 12345;
    return (unsigned int)(next/65536) % 32768;
}

void srand(unsigned int seed)
{
    next = seed;
}

So why? Is it possible that rand() has different implementations on multiple machines? What should I do?

I want to modify the other machine in such a way that I get 16807 from that machine too.
Please note that I love the rand implementation on my computer. Please show me a way that other machine gets same result with mine.

Thanks in advance.

Pro.Hessam
  • 819
  • 3
  • 11
  • 26
  • 16807 is probably the result on MacOS. It's a very bad random generator. [Why does rand() % 7 always return 0?](http://stackoverflow.com/q/7866754/995714) – phuclv Sep 23 '15 at 15:51

5 Answers5

8

Yes, rand() has different implementations; there's no requirement for them to be identical.

If you want consistent sequences across implementations and platforms, you can copy the sample implementation from the C standard section 7.20.2. Be sure to rename both rand and srand so they don't collide with the standard library's versions. You might need to adjust the code so the types have the same size and range across the implementations (e.g., use uint32_t from <stdint.h> rather than unsigned int).

EDIT: Given the new information from the comments, it looks like the requirements are different from what we thought (and I'm still not 100% clear on what they are).

You wants to generate random numbers on two systems consistent with a stored file that you've generated on one system, but you're unable to transfer it to the other due to network issues (the file is about a gigabyte). (Burning it to a DVD, or splitting it and burning it to 2 CDs, isn't an option?)

Suggested solution:

Write a custom generator that generates consistent results on both systems (even if they're not the same results you got before). Once you've done that, use it to re-generate a new 1-gigabyte data file on both systems. The existing file becomes unnecessary, and you don't need to transfer huge amounts of data.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • he he, which "Keith Thompson", this one or that one? I mean, the "We must do something. This is something. Therefore, we must do this." one? – Cheers and hth. - Alf Aug 19 '11 at 00:00
  • Yes, I am The One (i.e., The_Other). – Keith Thompson Aug 19 '11 at 00:01
  • OK, you are right. But what should I do? I want to implement a rand function manually that it gets same result as standard rand on my machine. How can I see rand implementation in my machine? Where is it?! I cannot find it. I want a rand function which gives me 16807 at first execution! gives same result on second execution , also in third execution and so on.. – Pro.Hessam Aug 19 '11 at 00:12
  • @Pro: What system are you using (compiler and operating system)? And why do you care about getting 16807 on the first execution? Would 16806 be too small? – Keith Thompson Aug 19 '11 at 00:16
  • @Pro : Use a third-party random library that _is_ guaranteed to give the same results across different platforms. [Boost.Random](http://www.boost.org/libs/random/index.html) may fit the bill... – ildjarn Aug 19 '11 at 00:16
  • I'm in macOSX 10.6 and I'm using g++ 4.2.1. The other machine is a linux and is using g++ 4.2.4. No, I don't want 16807 because it is small. I've generated a random file on my computer and I want the other machine have it. But due to some reasons I can't transfer the file. But I can transfer the generator. But when I run the generator on the other machine, I get completely different result. And I can't change my rand function know (use a third-party random library) because then I should change the random generated file on my machine which I'm not allowed to. – Pro.Hessam Aug 19 '11 at 00:17
  • The solution is simple: Don't use `srand`/`rand`. There are plenty of good random number generators out there. Boost provides a very good one, and so will the C++11 (and C++0x right now). Numerical Recipes provides a widely-used but not quite so good set (but a lot better than `srand`/`rand`). There are plenty of others as well. – David Hammen Aug 19 '11 at 00:30
  • @David Would you please read my comment which is added just before you? I can't change my random function now. Actually it's too late. – Pro.Hessam Aug 19 '11 at 00:34
  • Why can't you transfer the file? If you can do that, then you could just read data from the file rather than generating it, yes? – Keith Thompson Aug 19 '11 at 00:38
  • Yes but I can't. Target is a Internet Server. The file is about 1GB and I can't transfer it (to server) because my internet connection sucks. :) I hoped I could transfer generator and generate file on server too. But it seems I can't do that. – Pro.Hessam Aug 19 '11 at 01:04
  • It would be a great help if someone tells me how can I locate my computer's rand() implementation. – Pro.Hessam Aug 19 '11 at 01:05
  • 1
    @Pro: MacOSX is based on BSD. The [FreeBSD version of rand.c](http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/libc/stdlib/rand.c) *might* use the same algorithm, if they haven't diverged too much. But I still think that getting a consistent generator and regenerating the file on both systems is a better approach. – Keith Thompson Aug 19 '11 at 01:31
1

I think it's because int/unsigned int on your two platforms is a different size. Are ints/unsigned ints the same number of bytes on both machines/OSes you're compiling on? What platforms/compilers are you using?

Assuming the same rand/srand implementation, you need to use datatypes of the same precision (or appropriate casting) to get the same result. If you have stdint.h on your platform, try and use that (so you can define explicit sizes, e.g. uint32_t).

Joe
  • 41,484
  • 20
  • 104
  • 125
1

The C and C++ specifications do not define a particular implementation for rand or srand. They could be anything, as long as it is somewhat random. You cannot expect consistent output from different standard libraries.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Exactly. The standard specifies a consistent sequence for a given starting seed, but that guarantee doesn't apply across implementations. The standard also shows a sample implementation of `srand()` and `rand()`, but there's no requirement to use it. – Keith Thompson Aug 18 '11 at 23:51
  • OK, you are right. But what should I do? I want to implement a rand function manually that it gets same result as standard rand on my machine. How can I see rand implementation in my machine? Where is it?! I cannot find it. – Pro.Hessam Aug 19 '11 at 00:08
  • Does not address `What should I do?` – Mooing Duck Aug 19 '11 at 00:08
1

The rand implementations can be different. If you need identical behavior on different machines, you need a random number generator that provides that. You can roll your own or use someone else's.

I am not sure if the random generators in the C++0x library suffices. I think not. But reading the standardeese there makes my head spin.

Similarly, I'm not sure whether the Boost Random library suffices. But I think it's worth checking out. And there you have the source code, so at worst it can serve as basis for rolling your own.

Cheers & hth.,

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
0

Also, there are different Pseudo-RNG algorithms (e.g LCG vs Mersenne Twister)

http://en.wikipedia.org/wiki/Random_number_generation

C compiler on your first machine may use one, and the second machine may use another.

AlexK
  • 1,279
  • 8
  • 19