3

I am mocking the static random() method of the Math class in Java to better test a method that relies on generating random numbers. The code I am using is as follows:

@Mock
public double random() {
    return 1.0 - Double.MIN_VALUE;
}

This is my attempt at reaching a value as close to 1.0 as possible without being equal. (e.g. 0.999999999999...)

However, when I invoke the mocked Math.random() method I always get 1.0 as the value. It's almost as if subtracting the Double.MIN_VALUE does not affect the 1.0 at all.

Why does 1.0 - Double.MIN_VALUE result in 1.0 and how can I simulate the largest possible value of Math.random()?

terminex9
  • 671
  • 5
  • 10
  • See also http://stackoverflow.com/questions/7288334/increase-a-double-to-the-next-closest-value – Raedwald Jan 15 '15 at 07:35
  • See also http://stackoverflow.com/questions/155378/how-to-alter-a-float-by-its-smallest-increment-or-close-to-it – Raedwald Jan 15 '15 at 07:36
  • possible duplicate of [Java: Math.random() Max Value (double just less than 1)](http://stackoverflow.com/questions/15736885/java-math-random-max-value-double-just-less-than-1) – Raedwald Jan 15 '15 at 07:38

3 Answers3

2

double has limit precision. The closest number to 1.0 - Double.MIN_VALUE that can be represented as double is 1.0. That's why you get 1.0.

A double has 1 bit for sign, 11 bits for exponent and 52 bits for fraction. (Source)

The double value represented by 64 bits is (-1)^sign+1.b51b50...b0 x 2^(e-1023)

The closest to 1.0 you can get is when all the fraction bits are 1 and the exponent is e-1023==-1. That value is 0.1111..111 (53 ones) in binary.

To get that value in decimal :

double d = 0.0;
double exp =1.0;
for (int i=1;i<=53;i++) {
  exp=exp*2.0;
  d+=1.0/exp;
}
System.out.println (d);
System.out.println ("d==1.0? " + (d==1.0));

It prints

0.9999999999999999
d==1.0? false

If you add another iteration to the loop (i.e. i<=54) you get:

1.0
d==1.0? true
Eran
  • 387,369
  • 54
  • 702
  • 768
1

According to IEEE 754 double has 15.95 Decimal digits

http://en.wikipedia.org/wiki/IEEE_floating_point

so if you try double a = 1e0 - 1e-16 //or less you will have a == 1e0

Vitaly
  • 2,552
  • 2
  • 18
  • 21
1

double is not precise enough to show you the number generated when doing 1.0 - Double.MIN_VALUE. This is pointed out here when discussing Java primitive types. You may find this answer interesting as well: https://stackoverflow.com/a/15736977/4381697

Community
  • 1
  • 1
Troy Stopera
  • 302
  • 3
  • 15