1

I have a smple sop line as :

 System.out.println(0.0000877979+0.3067846127);

The output of above line is : 0.30687241060000003

But the expected is : 0.3068724106

I doubt,how come extra 0000003 at last came.

jps
  • 20,041
  • 15
  • 75
  • 79
Nirdesh Sharma
  • 734
  • 5
  • 14
  • This sum operation is calculated using double and result is printed as double. The extra 0000003 is result of float point arithmetic. Look at http://en.wikipedia.org/wiki/Floating_point – michal Jun 17 '13 at 07:23

5 Answers5

7

You need to understand what a double number is: it's a binary floating point number. As such, it can't represent all decimal numbers exactly. For example, take the number 0.2. There's no finite binary representation of that - just as there isn't a finite decimal representation of 1/3.

If you're interested in decimal digits then you should use BigDecimal. However, that may not actually be appropriate for what you're trying to achieve. What do the numbers mean in your case? Are they measured values from natural properties (weight, height etc) or are they "artificial", naturally decimal values such as financial ones? This affects which type you should use.

BigDecimal is different from double in three important ways:

  • It supports arbitrary precision (as many digits as you have memory for, basically)
  • It has a floating decimal point instead of a floating binary point. So while it still can't represent "a third" exactly, it can represent decimal values exactly.
  • It's a class type rather than a primitive. That's not important in terms of what numbers can be represented, but it's important to understand as a difference between the two types.

When constructing a BigDecimal, it's important that you start with accurate values - converting a double to BigDecimal is almost always a mistake. So if you've got user input as text, that's fine:

BigDecimal bd1 = new BigDecimal("0.0000877979");
BigDecimal bd2 = new BigDecimal("0.3067846127");
System.out.println(bd1.add(bd2)); // Prints 0.3068724106

In other cases you may start with another BigDecimal, or possibly an integer.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
4

This is because of using floating-point arithmetic in a binary environment. Look at this IEEE 754 standard for more information.

You should use BigDecimal class for pecision.

Use BigDecimal.valueOf(value) to convert the double to BigDecimal.

Translates a double into a BigDecimal, using the double's canonical string representation provided by the Double.toString(double) method.

AllTooSir
  • 48,828
  • 16
  • 130
  • 164
  • 1
    +1. You were faster ;) – Maroun Jun 17 '13 at 07:23
  • The binary part is the important bit here. `double` could be as long as you like, but it still wouldn't be able to represent 0.1 exactly. – Jon Skeet Jun 17 '13 at 07:26
  • And converting from a `double` to a `BigDecimal` is probably a bad idea - you'd want to convert from the original *string* representation, otherwise you've already lost information. – Jon Skeet Jun 17 '13 at 07:29
3

This is normal due to the limited nature of floating point numbers (float and double in Java). Please learn about floating point arithmetics (IEEE 754).

To get exact numbers use BigDecimal in Java.

Uwe Plonus
  • 9,803
  • 4
  • 41
  • 48
  • 1
    `BigDecimal` is a floating point type too. The important part is the *base* of the type (and the fact that `BigDecimal` is arbitrary precision, but the base is more important). – Jon Skeet Jun 17 '13 at 07:26
  • @JonSkeet extended my answer accordingly to your comment. – Uwe Plonus Jun 17 '13 at 07:29
0
BigDecimal bd = new BigDecimal(0.0000877979);
BigDecimal bd1 = new BigDecimal(0.3067846127);
System.out.print(bd.add(bd1).setScale(10,0));
shreyansh jogi
  • 2,082
  • 12
  • 20
0

To get the exact result, you can try like this,

BigDecimal b1= BigDecimal.valueOf(0.0000877979);
BigDecimal b2= BigDecimal.valueOf(0.3067846127);
System.out.println(b1.add(b2));
Sivaraman
  • 61
  • 7