Is there a difference between
int number = (int) (Math.random() * 1000);
and
int number = (int)(100 + Math.random() * 900);
for generating a random 3-digit number?
Your second expression guarantees to produce a 3-digit random number but the first one does not guarantee it. The first expression can produce any integer from 0 to 999.
You can also produce a 3-digit random integer as follows:
import java.util.Random;
public class Main {
public static void main(String[] args) {
Random random = new Random();
int number = random.nextInt(900) + 100;
System.out.println(number);
}
}
Math.random() from Java API:
Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0. Returned values are chosen pseudorandomly with (approximately) uniform distribution from that range.
For example:
// Generate random number
double rand = Math.random();
// Output is different everytime this code is executed
System.out.println("Random Number:" + rand);
//pseudorandom output: 0.5568515217910215
In your case:
int number = (int) (Math.random() * 1000); returns anything between 0 - 999
int number = (int)(100 + Math.random() * 900); returns anything between 100 - 999
More information from Java API
When this method is first called, it creates a single new pseudorandom-number generator, exactly as if by the expression
new java.util.Random()
This new pseudorandom-number generator is used thereafter for all calls to this method and is used nowhere else.
This method is properly synchronized to allow correct use by more than one thread. However, if many threads need to generate pseudorandom numbers at a great rate, it may reduce contention for each thread to have its own pseudorandom-number generator.
So the bottom line is:
Math.random() returns a pseudorandom double greater than or equal to 0.0 and less than 1.0.
In this kind of questions you should visit Java API instead. Hope it helped!
Related
This question already has answers here:
Generate a random double in a range
(7 answers)
Closed 6 years ago.
I have:
private Random rng = new Random();
double random = rng.nextDouble(1.5-0.5) + 0.5;
Because I want to generate a number between 50% and 150%. However it throws me an error. How do I get a number in that range using the random function?
Your problem is: you should read javadoc. Meaning: dont assume that some library method does something; instead: read the documentation to verify that your assumptions are correct.
In this case, check out Double.nextDouble ... and find:
Returns the next pseudorandom, uniformly distributed double value between 0.0 and 1.0 from this random number generator's sequence.
The point is: there is no method nextDouble() that takes a double argument! There is only one that goes without any argument; and that method by default returns a value between 0 and 1.
So, simply change your code to call that method without any argument!
That is because nextDouble does not receive parameters, and only return a double between 0.0 and 1.0. Use the following:
Random rng = new Random();
double max = 1.5;
double min = 0.5;
double random = rng.nextDouble(); // Double between 0.0 and 1.0
double percentage = random*(max-min) + min;
System.out.println(percentage);
If you read the error in the ide or just look at the java doc you will see clearly the reason...
method nextDouble() in the type Random is not applicable for the
arguments (double)
the random class has no such a method nextDouble() that takes a double as argument
BTW why don't you just generate a random integer between 50 and 150... that would make more sense for the implementation you desire...
something like
Random rand = new Random();
randomNum = minimum + rand.nextInt((maximum - minimum) + 1);
You can do something like 50% and 100%
public static void main(final String[] args) {
Random rng = new Random();
double random = rng.nextDouble();
if (random <= 0.5) {
System.out.println("50% " + random);
} else {
System.out.println("100% " + random);
}
}
I was playing around with the Random class's nextDouble() method as shown below. I expected nextDouble() to return a pseudorandom double value on the interval [-50.0, 50.0), however, after running the loop 1 billion times the output came out to maximum: 49.99999995014588 minimum: -49.99999991024878. I ran the loop without my manipulations of the output interval, and I got maximum: 0.9999999998979311 minimum: 0.0. I find this strange, because all I have done to the 0.0 that was returned is multiply it by 100.0 and subtract 50.0 from it. Why does this code snippet below never return exactly -50.0?
EDIT: Just for fun I ran the loop another 500 million times, and the output is now: maximum: 49.99999994222232 minimum: -49.999999996750944.
import java.util.Random;
public class randomTest{
public static void main(String[] args) {
double max = 0;
double min = 0;
Random math = new Random();
for(int a = 0; a < 1000000000; a++) {
double rand = math.nextDouble() * 100.0 - (100.0 / 2.0);
max = Math.max(max, rand);
min = Math.min(min, rand);
}
System.out.println("maximum: " + max + " minimum: " + min);
}
}
The javadoc clearly states that the upper bound on nextDouble() is exclusive not inclusive. That means that 1.0 will not be returned.
According to the javadoc, 0.0 will be returned .... with a probability of approximately 1 in 254. (That is one time in 18,014,398,509,481,984.)
(It boils down to determining whether two successive calls to next(27) will return zero. That is possible, if you examine the specification for the LCNG used by next(int).)
So, your code doesn't hit 50.0 because it can't. It should be able to hit -50.0 but you would probably need to run it in the order of 1.0E19 times for that to happen. You only ran it 5.0E8 times.
nextDouble() works by first generating a random long, i.e. an integer spread evenly between the numbers -263 and 263-1. If you generate one billion numbers, you are still generating only 109/264 = 5.421 x 10-11 of the possibilities, a tiny fraction. Thus the odds that any particular number will be generated are extremely tiny.
Even accounting for rounding, the chance is still small. Note that your output contains 16 significant digits, which means that there are somewhere between 1015 and 1016 possible sequences of decimal digits you can generate. If you only generate 109 of those, the probability of generating any particular number is 10-7.
Taken from oracle docs:
public double nextDouble() Returns the next pseudorandom, uniformly
distributed double value between 0.0 and 1.0 from this random number
generator's sequence. The general contract of nextDouble is that one
double value, chosen (approximately) uniformly from the range 0.0d
(inclusive) to 1.0d (exclusive), is pseudorandomly generated and
returned.
The method nextDouble is implemented by class Random as if by:
public double nextDouble() { return (((long)next(26) << 27) +
> next(27))
> / (double)(1L << 53); }
The hedge "approximately" is used in the foregoing description only because the next method is only
approximately an unbiased source of independently chosen bits. If it
were a perfect source of randomly chosen bits, then the algorithm
shown would choose double values from the stated range with perfect
uniformity.
[In early versions of Java, the result was incorrectly calculated as:
return (((long)next(27) << 27) + next(27))
> / (double)(1L << 54);
This might seem to be equivalent, if not better, but in fact it introduced a large nonuniformity because of the
bias in the rounding of floating-point numbers: it was three times as
likely that the low-order bit of the significand would be 0 than that
it would be 1! This nonuniformity probably doesn't matter much in
practice, but we strive for perfection.]
So its clear the the max value isn't included when generating the number,
Implement it yourself. Something work for me:
public double nextDoubleInclusive()
{
return myRandom.nextInt(Integer.MAX_VALUE) / (Integer.MAX_VALUE - 1.0);
}
notice that you probably didn't get 0.0 when running without the offset.
your "min" starts with 0.0.
with a little change to your code (min = 1) you can see that you aren't getting 0.0 (you could, not the odds are against you).
double max = 0;
double min = 1;
Random math = new Random();
for(int a = 0; a < 1000000000; a++) {
double rand = math.nextDouble();
max = Math.max(max, rand);
min = Math.min(min, rand);
}
System.out.println("maximum: " + max + " minimum: " + min);
maximum: 0.9999999989149039 minimum: 4.5566594941703897E-10
Had a look around the questions on this site and could not quite find the answer I was looking for about type casting the Math.random() method from double to int.
My question is, why does Math.random only return a 0 without parentheses whereas it returns random numbers when it is contained within the parentheses?
The first part of code returns 0:
int number;
number = (int) Math.random() * 10;
System.out.println("\nThe random number is " + number);
This code works however:
int number;
number = (int) (Math.random() * 10);
System.out.println("\nThe random number is " + number);
It should be noted I have seen a few different pieces of code on typecasting whereby some programmers seem to use both ways of casting.
This code:
number = (int) Math.random() * 10;
first calculates this:
(int) Math.random()
Since Math.random() returns a number from 0 up to but not including 1, if you cast it to int, it will round down to 0. Then when you multiply 10 to 0 you get 0.
Math.random() returns a number from 0 to 1. You want to cast the result of (Math.random()*10) to int, not the number you get from Math.random itself.
Numbers get rounded down. Therefore, for example, 0.3, which you can get from Math.random, gets rounded to 0. Again, you want to round the result of 0.3 times 10, which is 3. The parenthesis is important.
I was wondering if I am able to set the accuracy of the random double numbers that I generate.
Random generator = new Random();
double randomIndex = generator.nextDouble()*10000;
That produces the random numbers within 10000.
How am I able to set the accuracy to 4?
A couple of things. First, you mean "precision", not "accuracy". Second, you need to clarify why you want to do this, because a correct answer will depend on it.
If all you want to do is display the numbers with that precision, it is a formatting issue. You can use, e.g. System.out.printf("%.4f", value) or String.format().
If you are trying to to generate numbers with that precision, you could approximate by doing something like (rounding left out for simplicity):
double value = (int)(generateor.nextDouble() * 10000.0) / 10000.0;
Or if you want your range to be 0-10000 instead of 0-1:
double value = (int)(generateor.nextDouble() * 100000000.0) / 10000.0;
Due to the way floating-point numbers are stored, that will not be exact, but perhaps it is close enough for your purposes. If you need exact, you would want to store as integers, e.g.:
int value = (int)(generator.nextDouble() * 10000.0);
Then you can operate on that internally, and display as:
System.out.printf("%.4f", value / 10000.0);
Adjust multiplication factor above if you meant you wanted your range to be 0-10000.
If you are merely trying to generate a number in [0, 10000), you can use Random.nextInt(int) with a range specified, or simply cast the value to an int as above (optionally rounding).
Random generator = new Random();
double randomIndex = generator.nextDouble()*10000;
randomIndex=Math.floor(randomIndex * 10000) / 10000;//this is the trick
If you want 4 digits after the decimal mark you can simply do the following:
Random generator = new Random();
double randomIndex = Math.floor(generator.nextDouble()*10000 * 10000) /10000;
Random generator = new Random();
double randomIndex = Double.parseDouble(new DecimalFormat("##.####")
.format(generator.nextDouble() * 10000));
Simply
double result = generator.nextLong() / 10000.0;
Note, hoewever, that you can never be sure that the number has exactly 4 decimals, whenever you hit a number that is not representable in a double.
Anyway, the requirement is silly, because a double simply does not have decimal positions. Hence, to request 4 of them makes no sense.
I was trying to explain the random number generator in Java to a friend when he kept getting the same numbers every time he ran the program. I created my own simpler version of the same thing and I too am getting the same exact numbers he was getting every time I run the program.
What am I doing wrong?
import java.util.*;
public class TestCode{
public static void main(String[] args){
int sum = 0;
Random rand = new Random(100);
for(int x = 0; x < 100; x++){
int num = (rand.nextInt(100)) + 1;
sum += num;
System.out.println("Random number:" + num);
}
//value never changes with repeated program executions.
System.out.println("Sum: " + sum);
}
}
The final five numbers out of the 100 are:
40
60
27
56
53
You have seeded the random generator with a constant value 100. It's deterministic, so that will generate the same values each run.
I'm not sure why you chose to seed it with 100, but the seed value has nothing to do with the range of values that are generated (that's controlled by other means, such as the call to nextInt that you already have).
To get different values each time, use the Random constructor with no arguments, which uses the system time to seed the random generator.
Quoting from the Javadoc for the parameterless Random constructor:
Creates a new random number generator. This constructor sets the seed
of the random number generator to a value very likely to be distinct
from any other invocation of this constructor.
Quoting the actual code in the parameterless Random constructor:
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
This:
Random rand = new Random(100);
You're giving the random number generator the same seed (100) each time you start the program. Give it something like the output from System.currentTimeMillis() and that should give you different numbers for each invocation.
Random number generators are really only pseudo-random. That is, they use deterministic means to generate sequences that appear random given certain statistical criteria.
The Random(long seed) constuctor allows you to pass in a seed that determines the sequence of pseudo-random numbers.
Please see the below code to generate a random number from a pool of random numbers.
Random r = new Random(System.currentTimeMillis());
double[] rand = new double[500];
for(int i=0;i<100;i++){
rand[i] = r.nextDouble();
}
double random_number = rand[randomInt];