Sparkles

that were shone when I got tempered!

Why is [427.14 + 61.02 != 488.16] in double and how to do it in correct way?

leave a comment »

Followings are some scenarios that I experienced and information that I found in The need for BigDecimal by John Zukowski and StackOverFlow posts.

The BigDecimal class stores floating-point numbers with practically unlimited precision. To manipulate the data, you call the add(value), subtract(value), multiply(value), or divide(value, scale, roundingMode)methods.

To output BigDecimal values, set the scale and rounding mode with setScale(scale, roundingMode), or use either the toString() or toPlainString() methods. The toString() method may use scientific notation whiletoPlainString() never will.

Available roundingMode enumerations

  • CEILING which always rounds towards positive infinity
  • DOWN which always rounds towards zero
  • FLOOR which always rounds towards negative infinity
  • UP which always rounds away from zero
  • HALF_DOWN which always rounds towards nearest neighbor, unless both neighbors are equidistant, in which case it rounds down
  • HALF_UP which always rounds towards nearest neighbor, unless both neighbors are equidistant, in which case it rounds up
  • UNNECESSARY which asserts exact result, with no rounding necessary

Don’t create a BigDecimal from a primitive type like this.

double dd = .35;
BigDecimal d = new BigDecimal(dd); // here d = .34999999999999997779553950749686919152736663818359375

Instead create a BigDecimal as follows


BigDecimal d = new BigDecimal(".35");

After creating the value, you can explicitly set the scale of the number and its rounding mode with setScale(). Like other Number subclasses in the Java platform, BigDecimal is immutable, so if you call setScale(), you must “save” the return value:


d = d.setScale(2, RoundingMode.HALF_UP);

Example :


package floatingPoints;

import java.math.BigDecimal;

public class TestingFloatingPoints {

public static void main(String[] args) {

 TestingFloatingPoints testingFloatingPoints = new TestingFloatingPoints();
 testingFloatingPoints.floatingPointsInDouble();
 testingFloatingPoints.floatingPointsInBigDecimle();

 }

 private void floatingPointsInDouble() {

 double total = 427.14;
 double tax = 61.02;
 double taxedTotal = tax + total; // This is 488.15999999999997

 }

 private void floatingPointsInBigDecimle() {

 BigDecimal total = new BigDecimal("427.14");
 BigDecimal tax = new BigDecimal("61.02");
 BigDecimal taxedTotal = total.add(tax); // This is 488.16

}

}

According to the Peter Lawry, The exact reason is that you get a number slightly less than you expect is that 427.14 is actually 427.1399999999999863575794734060764312744140625 and 61.02 is actually 61.02000000000000312638803734444081783294677734375 and when you add these together you get the nearest double value to 488.15999999999998948396751075051724910736083984375 which is slightly less than you expected. If you round this to 2 decimal places you get the expected answer 488.16

You can check the corresponding binary value for each floating point number by using binaryconvert.com.

Another comment for floating point numbers in StackOverFlow

Remember, a decimal value can not be represented exactly in a computer” It can, it just isn’t in IEEE 754 floating point. – T.J. Crowder

It can, if you have infinite memory. In a practical sense, and for the general case, it can’t. – Óscar López

@ Óscar: No, that’s not true at all. It’s just a matter of how many decimal places you want to hold. Or more accurately, how many significant digits you want. To get about the same range as a double but with perfect decimal accuracy, you only need about 56 significant digits and an indicator of where the decimal point goes. Of course, decimal numbers have their own issues, such as not being able to accurately store 1 / 3. 😉 – T.J. Crowder

Advertisements

Written by Namal Fernando

August 6, 2013 at 4:31 pm

Posted in Java, Q&A

Tagged with , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Ruth's Reflections

Contemplations from quakey quirky Christchurch

TED Blog

The TED Blog shares interesting news about TED, TED Talks video, the TED Prize and more.

Ziplok

Learn and discover simple things

Meihta Dwiguna Saputra's Knowledge Base

~In learning you will teach and in teaching you will (re)learn~

The Java Blog

Thoughts, tips and tricks about the Java programming language

Sparkles

that were shone when I got tempered!

%d bloggers like this: