简体   繁体   中英

Generating a random double number of a certain range in Java

I have seen posts which explains pretty much this question but they all used integer values and I honestly do not fully understand it hence this question:

I am trying to generate random numbers from the range (-1554900.101) to (52952058699.3098) in java and I was wondering if anyone could explain this to me as I really want to understand it.

My thoughts: will this be a right approach? 1) Generate a random integer number within my specified range 2) Divide the generated number by pi to get float/double random results

Thanks in advance.

Here's the idea. You want a random number in a range , let's say [-1.1,2.2] , to start with a simple example. That range has length 3.3 since 2.2 - (-1.1) = 3.3 . Now most "random" functions return a number in the range [0,1) , which has length one, so we have to scale our random number into our desired range.

Random random = new Random();
double rand = random.nextDouble();
double scaled = rand * 3.3;

Now our random number has the magnitude we want but we must shift it in the number line to be between the exact values we want. For this step, we just need to add the lower bound of the entire range to our scaled random number and we're done!

double shifted = scaled + (-1.1);

So now we can put these parts together in a single function:

protected static Random random = new Random();
public static double randomInRange(double min, double max) {
  double range = max - min;
  double scaled = random.nextDouble() * range;
  double shifted = scaled + min;
  return shifted; // == (rand.nextDouble() * (max-min)) + min;
}

Of course, this function needs some error checking for unexpected values like NaN but this answer should illustrate the general idea.

double lower = -1554900.101;
double upper = 52952058699.3098;
double result = Math.random() * (upper - lower) + lower;

It should be something like:

double rnd = Math.random();

double result = ((long)(rnd * (529520586993098L - (-15549001010L) + 1)) -15549001010L) / 10000.0;

The + 1 will balance for the fact that the range is [0;1[ so the upper range is excluded.

We first try to find an "integer" (really long) range and we add 1 to balance the fact that the last number is excluded, so 529520586993098L + 15549001010L + 1 , then we multiply it by rnd , cast it to long and subtract 15549001010L to shift it back and in the end divide it by 10000.0 to make it in the right "range".

This is probably more clear:

long range = 529520586993098L + 15549001010L + 1;

double temp = rnd * range;
long temp2 = (long)temp;
temp2 -= 15549001010L;

double result = temp2 / 10000.0;

This not how I would do it.

  • Generate a random double. The result is between 0 and 1.
  • Multiply this number by (highLimit - lowLimit) (52952058699.3098 - -1554900.101)
  • Add the lowLimit (random + -1554900.101)

Here you go. You have a random number between low and high limit.

Random.nextDouble returns a double in the range [0, 1[ so use that, multiply with your range size (52952058699.3098 + 1554900.101) and then offset the result (subtract 1554900.101) to get your number.

Not sure how exact you need this though, without doing some further analysis you might get numbers outside your range due to how doubles are handled.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM