Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Math.random closed double interval

Tags:

java

random

How do I generate random double values in a closed interval [x;y] in Java, e.g [0;10]? The API of Math.random() says it returns values in [0;1), so multiplying by 10 does not help (as well as multiplying by 11).

like image 990
tintinnabulum Avatar asked Mar 03 '23 04:03

tintinnabulum


2 Answers

Edit: I've looked into it further.

To get the next higher possible double value in magnitude, use Math.ulp(double).

double number = 10.0 + Math.ulp(10.0);

The next higher value for 10.0 is 10.000000000000002

In case of the random number generation:

double randomNumber = Math.random() * (10.0 + Math.ulp(10.0));

https://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#ulp(double)


My old theory which is not true:

2e-1074 is the smallest positive nonzero value of type double. The constant for this is Double.MIN_VALUE. So multiplying 10 + 2e-1074 with Math.random() should in theory give you a random number in the range [0;10]

double randomNumber = Math.random() * (10.0 + Double.MIN_VALUE);

Java docs for Double.MIN_VALUE: https://docs.oracle.com/javase/7/docs/api/java/lang/Double.html#MIN_VALUE

like image 99
svdragster Avatar answered Mar 07 '23 11:03

svdragster


Very interesting question. I can think of two approaches to try. (1) Double floats are actually integers scaled by an exponent. How many distinct double float values are there in [0, 10]? You can generate an integer in [0, 1, 2, ... n] where n is that number, and then scale it to get a float. As an added wrinkle, there are different granularities of floats in different ranges. I suspect that you'll have to look at ranges of the form [2^m, 2^(m + 1)].

(2) Rejection method. Figure out a way to generate numbers in some range greater than [0, 10], then just reject any which don't fall in that range.

Good luck and have fun.

like image 32
Robert Dodier Avatar answered Mar 07 '23 11:03

Robert Dodier