4

I have the following methods. The method rnd, returns a single random integer between two bounds:

  /* Create next batch of 55 random numbers */
  void advance_random (){
int j1;
double new_random;
for(j1=0; j1<24; j1++){
  new_random = oldrand[j1]-oldrand[j1+31];
  if(new_random<0.0){
    new_random = new_random+1.0;
  }
  oldrand[j1] = new_random;
}
for(j1=24; j1<55; j1++){
  new_random = oldrand[j1]-oldrand[j1-24];
  if(new_random<0.0){
    new_random = new_random+1.0;
  }
  oldrand[j1] = new_random;
}
 } //advance_ramdom

  /* Fetch a single random number between 0.0 and 1.0 */
  double randomperc(){
jrand++;
if(jrand>=55){
  jrand = 1;
  advance_random();
}
return((double)oldrand[jrand]);
  } //randomPerc

  /* Fetch a single random integer between low and high including the bounds */
  synchronized int rnd (int low, int high){
int res;
if (low >= high){
  res = low;
} else {
  res = low + (int)(randomperc()*(high-low+1));
  if (res > high){
    res = high;
  }
}
return (res);
  } // rnd

How do I modify this so that the number returned mod2 =0?

Thanks

Labra
  • 51
  • 1
  • 5

5 Answers5

8

if you can get a random number in range [a, b] then all you have to do is get a random number in the range [(a+1)/2, b/2] and multiply it by 2 to get a random even number in range [a, b]

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • 1
    You need to round up the lower bound, otherwise an even between 3 and 5 can return 2. `2 * rnd((low+1)/2, high/2)` – Peter Lawrey Jul 05 '11 at 11:15
5

Use a bit-mask to force the least-significant bit to be zero:

x = x & ~1;
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • 2
    Note that the range should be adapted before to ensure a random distribution. For example, if the range is [2, 4], you'll get twice more 2s than 4s. You should thus extend the range to [2, 5] to get a random distribution between 2 and 4. This becomes negligible for very large ranges, of course. And if the range is [3, n], you'll get some 2s, which are out of range. – JB Nizet Jul 05 '11 at 10:55
2

Multiply the result you get from your code by two at the end - still random, and divisble by 2!

Jon Egerton
  • 40,401
  • 11
  • 97
  • 129
1

how about using:

return res & ~1;

qbert220
  • 11,220
  • 4
  • 31
  • 31
0

In Java 1.7 or later, I would use ThreadLocalRandom:

import java.util.concurrent.ThreadLocalRandom;

// Get even random number within range [min, max]
// Start with an even minimum and add random even number from the remaining range
public static int randEvenInt(int min, int max) {
    if (min % 2 != 0) ++min;
    return min + 2*ThreadLocalRandom.current().nextInt((max-min)/2+1);
}

// Get odd random number within range [min, max]
// Start with an odd minimum and add random even number from the remaining range
public static int randOddInt(int min, int max) {
    if (min % 2 == 0) ++min;
    return min + 2*ThreadLocalRandom.current().nextInt((max-min)/2+1);
}

The reason to use ThreadLocalRandom is explained here. Also note, that the reason we +1 to the input to ThreadLocalRandom.nextInt() is to make sure the max is included in the range.

Community
  • 1
  • 1
rouble
  • 16,364
  • 16
  • 107
  • 102