3

As I am rewriting application which uses randoms quite often from C to Java, and I would like to ask if there is any critical difference between

rand() % 256; // C code

and this

import java.util.Random;
...
Random rand = new Random();
rand.nextInt(256);

Does anyone know if it works the same way or, as I already wrote, there is some critical difference?

Mureinik
  • 297,002
  • 52
  • 306
  • 350
Martin Plávek
  • 335
  • 1
  • 3
  • 17
  • 3
    what do you mean, critical difference? obviously one critical difference is that one's C and the other's Java... – Marc B Dec 12 '14 at 14:24
  • Obviously he asks if there is a critical difference in behaviour, e.g. the range of possible results. Come on guys, that's not a stupid thing to ask. – atamanroman Dec 12 '14 at 14:25
  • In addition to being written in different languages, they might (I think even *probably*) use different [PRNG functions](http://en.wikipedia.org/wiki/Pseudorandom_number_generator). – Elliott Frisch Dec 12 '14 at 14:26
  • you can check this link so you will understand in java: http://stackoverflow.com/questions/363681/generating-random-integers-in-a-range-with-java its best. – Rickey Dec 12 '14 at 14:28
  • As atamanroman said, I am asking how both of them behave, because I would like to have identical behavior of my application. Or at least mostly identical. Elliot Frisch: So I should check PRNG functions of both of them? – Martin Plávek Dec 12 '14 at 14:28

4 Answers4

5

Apart from possible differences in probability distributions caused by employing different pseudo-random algorithms, there is no difference between the two: both snippets generate a number between zero and 255, inclusive of both ends.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Yeah it might matter that `rand()` is seeded once per application while you get a new seed everytime you create a `new Random()`. Using a `Random` as a singleton may cause performance problems - I can't speak for the c version. – atamanroman Dec 12 '14 at 14:31
  • Whether Random is local or a field, doesn't matter except for performance. i.e. it's no more or less random unless you look at very long sequences of numbers. – Peter Lawrey Dec 12 '14 at 14:32
  • The built in Random repeats itself after 2^^48 values. If this is a problem use SecureRandom which is more expensive but more random on that scale. – Peter Lawrey Dec 12 '14 at 14:33
  • While the second example is more efficient it will repeat eventually. – Peter Lawrey Dec 12 '14 at 14:34
  • 1
    @PeterLawrey You are right, I shouldn't go into unnecessary details on this - it's very much irrelevant to what OP is asking. Thanks! – Sergey Kalinichenko Dec 12 '14 at 14:37
1

As far as functionality is concerned, both promise a (pseudo-)randomly distributed int in the range of [0..255]. The implementation specifics (e.g., the PRNG algorithm used) may be different, but you really shouldn't rely on those anyway.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
1

I'll mostly go with @Mureinik's answer and just add that you should be aware that the C version does not provide uniformly distributed numbers, due to the modulus operation (IIRC RAND_MAX has to divide evenly by your n for this to be the case).

If this is important to you, you probably shouldn't be using rand() anyways in the first place though...

Cheers,

Anders R. Bystrup
  • 15,729
  • 10
  • 59
  • 55
0

You should not use the mod % operator to narrow the random range, because the probability of the numbers will not be the same· For example, if RAND_MAX is 256, the number 1 would have a higher probability than the rest.

You can test this in Python, there is roughly twice the number of zeros than ones:

>>> sorted([(random.randint(0, 2) % 2) for x in range(100)])
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

To get the same probability distrubution as the Java cone from C you should do something like:

/* Returns a random number from 0 to limit inclusive */
int rand_int(int limit) {
  return ((long long)limit * rand()) / RAND_MAX
}
vz0
  • 32,345
  • 7
  • 44
  • 77
  • Thanks! I will try it. Didn't even quess that there are numbers with higher propability. – Martin Plávek Dec 12 '14 at 14:42
  • 1
    This doesn't apply to powers of two. Every bit has an equal chance of being 0 or 1 and when you `% powerOf2` you mask out the upper bits and the lower bits are unchanged, just as random as they were. – Peter Lawrey Dec 12 '14 at 14:42
  • 1
    @PeterLawrey as long as RAND_MAX is also a (power of two - 1), yes. But the c std says nothing about it. http://stackoverflow.com/questions/4945698/is-the-value-of-rand-max-always-2n-1 – vz0 Dec 12 '14 at 15:08
  • Is RAND_MAX inclusive or exclusive? If it is inclusive, you appear to have a very small chance of getting RAND_MAX, and thus `limit` inclusive. – Peter Lawrey Dec 12 '14 at 16:56
  • @PeterLawrey Yes, that is what the comment says. – vz0 Dec 13 '14 at 16:19
  • Perhaps you could re-write it so `limit` has the same chance as every other number. – Peter Lawrey Dec 13 '14 at 17:54