Generating a random double number of a certain range in Java
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.
Generating random double between 1 and 100 in C
What you're doing would "work", but probably not in the way you intend to. The key is to define what you mean by random double. Normally, what we'd mean by this is a double with the maximal precision the system allows.
Fortunately, we know that the number returned by rand
is between 0 and RAND_MAX
, whatever that value happens to be. (32767 used to be a common choice.) We can divide by this limit to generate a value between 0 and 1, which then can be scaled to whatever range you need, like so:
double random = ((double) rand() / RAND_MAX) * (100 - 1) + 1;
If you wanted a value between 1.5 and 9, you'd do it in a very similar way:
double random = ((double) rand() / RAND_MAX) * (9 - 1.5) + 1.5;
Generating a random double in an exclusive range
Your first code is quite correct.
double myvalue;
do {
myvalue = myrandom.nextDouble() * (upper - lower) + lower;
} while (myvalue == lower); // Replace != with ==
Simply replace !=
with ==
. It is not true that this is not efficient.
A look to efficiency of the code.
Taking a look on the code of nextDouble
you can see that it is calculated generating a random long value.
It means that basically you will have 1 possibility to repeat the loop over 2 * 9,223,372,036,854,775,807 (the range of long values minus 1).
Additional Note: because you are using double
and not a BigDecimal
you can obtain a myvalue
that is close to the lower
bound, but lower than it, so it is better to change the code to exclude also values lower than lower
. It doesn't change the efficiency of your code.
double myvalue;
do {
myvalue = myrandom.nextDouble() * (upper - lower) + lower;
} while (myvalue <= lower); // Replace != with <=
Generate a random double between -1 and 1
This will seed the random number generator and give a double in the range of -1.0 to 1.0
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
double random_value;
srand ( time ( NULL));
random_value = (double)rand()/RAND_MAX*2.0-1.0;//float in range -1 to 1
printf ( "%f\n", random_value);
return 0;
}
How to generate a random double value in a specific range using Kotlin?
try this
double random = ThreadLocalRandom.current().nextDouble(51.3257, 52.4557);
Java: Generating a random double between the range of a negative double and a positive double
Now you have included all your code in the question, so my answer is changed to:
When it printed 0.3567587946356543
then it comes from the 20% part with range -.75 to 0.90 when the first Math.random()
call in if(Math.random() > 0.19){
becomes false.
Old answer:
I think you forgot the minus at the lower value:
double upper = 0.25;
double lower = -0.10;
double result = Math.random() * (upper - lower) + lower;
How to generate a random double number in the inclusive [0,1] range?
After taking a shower, I have conceived of a potential solution based on my understanding of how a random floating point generator works. My solution makes three assumptions, which I believe to be reasonable, however I can not verify if these assumptions are correct or not. Because of this, the following code is purely academic in nature, and I would not recommend its use in practice. The assumptions are as follows:
- The distribution of
random.NextDouble()
is uniform - The difference between any two adjacent numbers in the range produced by
random.NextDouble()
is a constant epsilone
- The maximum value generated by
random.NextDouble()
is equal to1 - e
Provided that those three assumptions are correct, the following code generates random doubles in the range [0, 1].
// For the sake of brevity, we'll omit the finer details of reusing a single instance of Random
var random = new Random();
double RandomDoubleInclusive() {
double d = 0.0;
int i = 0;
do {
d = random.NextDouble();
i = random.Next(2);
} while (i == 1 && d > 0)
return d + i;
}
This is somewhat difficult to conceptualize, but the essence is somewhat like the below coin-flipping explanation, except instead of a starting value of 0.5, you start at 1, and if at any point the sum exceeds 1, you restart the entire process.
From an engineering standpoint, this code is a blatant pessimization with little practical advantage. However, mathematically, provided that the original assumptions are correct, the result will be as mathematically sound as the original implementation.
Below is the original commentary on the nature of random floating point values and how they're generated.
Original Reply:
Your question carries with it a single critical erroneous assumption: Your use of the word "Correct". We are working with floating point numbers. We abandoned correctness long ago.
What follows is my crude understanding of how a random number generator produces a random floating point value.
You have a coin, a sum starting at zero, and a value starting at one half (0.5).
- Flip the coin.
- If heads, add the value to the sum.
- Half the value.
- Repeat 23 times.
You have just generated a random number. Here are some properties of the number (for reference, 2^23 is 8,388,608, and 2^(-23) is the inverse of that, or approximately 0.0000001192):
- The number is one of 2^23 possible values
- The lowest value is 0
- The highest value is 1 - 2^(-23);
- The smallest difference between any two potential values is 2^(-23)
- The values are evenly distributed across the range of potential values
- The odds of getting any one value are completely uniform across the range
- Those last two points are true regardless of how many times you flip the coin
- The process for generating the number was really really easy
That last point is the kicker. It means if you can generate raw entropy (i.e. perfectly uniform random bits), you can generate an arbitrarily precise number in a very useful range with complete uniformity. Those are fantastic properties to have. The only caveat is that it doesn't generate the number 1.
The reason that caveat is seen as acceptable is because every other aspect of the generation is so damned good. If you're trying to get a high precision random value between 0 and 1, chances are you don't actually care about landing on 1 any more than you care about landing on 0.38719, or any other random number in that range.
While there are methods for getting 1 included in your range (which others have stated already), they're all going to cost you in either speed or uniformity. I'm just here to tell you that it might not actually be worth the tradeoff.
Related Topics
How Would You Implement an Lru Cache in Java
How to Convert a Char Array Back to a String
Running Code After Spring Boot Starts
Getting the Filenames of All Files in a Folder
Java 8: Lambda-Streams, Filter by Method with Exception
How to Hash Some String with Sha256 in Java
How to Execute a Java .Class from the Command Line
Hibernate 5 :- Org.Hibernate.Mappingexception: Unknown Entity
How to Add an Actionlistener Onto a Jbutton in Java
Date and Time Conversion to Some Other Timezone in Java
How to Move My Jmenubar to the Screen Menu Bar on MAC Os X
How to Mark Jtable Cell Input as Invalid
Java Simpledateformat Always Returning January for Month
Calling One Jframe from Another Using Timer Without Any Buttons