0

How to properly truncate a double in Java, so for example 1.99999999999999999 is always truncated to 1 and not rounded upto 2 as is the case in the sample below.

    double d1 = 1.999999999999999999;
    double d2 = 1.0; 
    long i1 = (long)Math.floor(d1);
    long i2 = (long)Math.floor(d2);
    System.out.println("i1="+i1 + " i2="+i2); //i1 == 2

Running sample here: http://www.browxy.com/SubmittedCode/42603

Solution

Use BigDecimal which has arbitary precision

BigDecimal bd = new BigDecimal("0.9999999999999999999999999999");
bd = bd.setScale(0, BigDecimal.ROUND_DOWN); //truncate
volting
  • 16,773
  • 7
  • 36
  • 54

3 Answers3

7

1.99999999999999999 is not rounded up to 2, it is 2.

System.out.println(1.999999999999999999);      // 2
System.out.println(1.999999999999999999 == 2); // true

Floating-point numbers aren't infinitely precise. There aren't enough bits in the storage format Java uses (IEEE double) to distinguish between 1.999999999999999999 and 2.

If you need more accuracy than that, try a different number format, such as BigDecimal.

bobince
  • 528,062
  • 107
  • 651
  • 834
  • BigDecimal doesn't seem to be able to handle this much precision either - see here http://www.browxy.com/SubmittedCode/42606 – volting Sep 21 '13 at 20:56
  • 3
    @volting BigDecimal can distinguish new BigDecimal("1.999999999999999999") from two, represent it exactly, and print it correctly. The referenced article used Double, rather than BigDecimal, to parse the string, so that the new BigDecimal could only have a value that could be exactly represented in double. – Patricia Shanahan Sep 21 '13 at 21:23
1

I think your d1 has too much precision to be expressed as a double.

If you print d1 directly to System.out you get 2.0.

So any call to floor or round has no effect.

If you need such a precision you should go for BigDecimal.

Marc
  • 1,900
  • 14
  • 22
0

Some of the examples are explained here

Documentation

double d1 = 1.999999999999999999;
double d2 = 1.0; 
long i1 = (long)Math.round(d1);
long i2 = (long)Math.floor(d2);

System.out.println("i1="+i1 + " i2="+i2);

Then the output will be

i1=2 i2=1
Naveen Kumar Alone
  • 7,536
  • 5
  • 36
  • 57