0

I have a simple question and I'm a little rusty on random number generation. I want to generate large odd integers (I'm using doubles since my numbers could be outside the int range) and I can't quite figure out how to get rid of the decimals in the random number generation and have the number be odd.

Right now I just have:

N = nMin + (nMax - nMin) * rand.nextDouble();

Which as I said gives me any random number (with decimals) between nMin and nMax. Any help would be much appreciated!

Ryan Sayles
  • 3,389
  • 11
  • 56
  • 79
  • 2
    "outside the int range" - outside `long` as well? – Mysticial Sep 11 '12 at 21:42
  • Yes, it would need to be a double – Ryan Sayles Sep 11 '12 at 21:48
  • In that case, you probably have a design problem. If you're generating a uniform distribution of integers that will span more than a `long`, the probability that the generated number will be small enough (and thus precise enough) in a `double` to distinguish between an odd and even will be vanishingly small. – Mysticial Sep 11 '12 at 21:50

3 Answers3

6

If your numbers can be out of the int range, then you should use long, or failing in that, BigInteger.

Use the information in this question to create a random BigInteger, and if it is even simply add 1 to it.

BigInteger randomOdd(BigInteger min, BigInteger max) {
    BigInteger range = max.subtract(min);

    // expected iterations: 2 - max iterations: infinite
    BigInteger tmp;
    do {
        tmp = new BigInteger(n.bitLength(), rng); // rng is your Random Number Generator
    } while (tmp.compareTo(range) >= 0);

    BigInteger result = min.add(tmp);

    // force the result to be odd
    // TODO: will this push it over max?
    result = result.or(BigInteger.ONE); 

    return result;
}

Alternatively, you could use a method on the BigInteger class: BigInteger.probablePrime():

public static BigInteger probablePrime(int bitLength, Random rnd)

Returns a positive BigInteger that is probably prime, with the specified bitLength. The probability that a BigInteger returned by this method is composite does not exceed 2^100.

Parameters:

  • bitLength - bitLength of the returned BigInteger.
  • rnd - source of random bits used to select candidates to be tested for primality.

Returns:

  • a BigInteger of bitLength bits that is probably prime

If it's probably prime, it's also probably odd.

Community
  • 1
  • 1
corsiKa
  • 81,495
  • 25
  • 153
  • 204
  • I think I understand that. How would I set the range to be any given minimum instead of 0? – Ryan Sayles Sep 11 '12 at 21:48
  • I added some code that should do the trick, or at least get you started. I see an edge case around `max` potentially, but I'm sure working out the bugs and edge cases are things that can be tackled as they come up. – corsiKa Sep 11 '12 at 21:50
  • You can just do `result.or(BigInteger.ONE)`. – obataku Sep 11 '12 at 21:55
  • @oldrinb I like it - I'll add that in. – corsiKa Sep 11 '12 at 21:57
  • @rsay3 I added more information about Probable Prime - if it's probably prime, it's probably odd too. And just in case you were looking for primes anyway this saves you some more time! – corsiKa Sep 11 '12 at 21:58
  • @corsiKa you need to reduce the interval by one in the case that `max` is even :-) both your original `mod` followed by `add` and my `or` will push it past `max` unless care is taken. – obataku Sep 11 '12 at 22:01
  • Thank you! You guys have helped a lot. I just have one more question. Say I wanted the max value to come from user input. Is there an easy way to still impliment this? I know you can't have a scanner do input.nextBigInteger or something of the sort and you can't cast input.nextDouble to a BigInteger – Ryan Sayles Sep 11 '12 at 22:06
  • @rsay3 Take the input as a `String` from the scanner and create the `BigInteger` using the [`BigInteger(String)`](http://docs.oracle.com/javase/6/docs/api/java/math/BigInteger.html#BigInteger%28java.lang.String%29) constructor. – Brian Sep 11 '12 at 22:07
  • Yep, just like Brian says, you can do `BigInteger max = new BigInteger(scanner.next());` – corsiKa Sep 12 '12 at 14:57
1

(long)(expression) will cast expression to an long (a 64-bit integer), truncating the decimals (thus effectively rounding towards zero). Creating odd numbers can be done by first creating an integer and then multiplying it by two and adding one (embarrassing edit). (You'll probably be able to do the math for how you need to adjust nMin and nMax yourself. :-) )

Aasmund Eldhuset
  • 37,289
  • 4
  • 68
  • 81
0

Getting rid of decimals is a common issue. One trick is to multiply by 100, and then cast that result to an int(or long). This is a good practice for you to get familiar!!

Caffeinated
  • 11,982
  • 40
  • 122
  • 216