-7

is there any chance that PC adds 2 decimal float numbers incorrectly?

0.13 + 0.21 =0.340000000004

If we human adds these 2 number then we won't have any extra fraction error right? cos it 's not logic, but Computer could have.

Is this Computer problem?

How to use BigDecimal in Java properly?

Tum
  • 3,614
  • 5
  • 38
  • 63
  • 5
    Just use `int`, or `long`, and count in cents, not dollars (or whatever currency you have). – tobias_k Jan 31 '14 at 11:57
  • 4
    what do you mean by ***PC***? It is a floating point issue... – UmNyobe Jan 31 '14 at 11:57
  • you must know that when we're talking about floating point numbers, 0.13 is not 0.130000000000000000000000000 and 0.21 is not 0.2100000000000000000000000000 – Leo Jan 31 '14 at 11:58
  • 3
    I don't understand why so many down votes, this is a question that indeed confuses a lot of people – cahen Jan 31 '14 at 11:59
  • Try adding 1/3 to 1/3 in decimal and then tell me humans do a better job. This may be an interesting read: [Why does for loop using a double fail to terminate](http://stackoverflow.com/questions/19907186/why-does-for-loop-using-a-double-fail-to-terminate/19907216#19907216) or [Whats wrong with this simple 'double' calculation?](http://stackoverflow.com/q/16707397/2187042) – Richard Tingle Jan 31 '14 at 12:05
  • @cahen - I agree. Upvoted the question :-) Made an explanation why this happends further down – Björn Hallström Jan 31 '14 at 12:53
  • 1
    @cahen Downvotes are because the question shows no research effort. A quick search on Google or Wikipedia already answers. Also see http://stackoverflow.com/help/how-to-ask – Alessandro Da Rugna Jan 31 '14 at 14:06
  • I get it now, and I agree – cahen Jan 31 '14 at 14:24

3 Answers3

3

It is not compulsory, but it is good practice for four reasons at least:

  1. currency sums can grow arbitrarily large (suppose you work for a bank, you do not want the system to go crazy on overflows). While a billion $ might seem a large sum, consider that in some currencies a billion or even a trillion might not be that much.
  2. float numbers are subject to erosion because of floating point approximation. Still in the bank example, you do not want to steal or give away cents on any transaction and you want the bank account to be empty, not containing 1e-37$
  3. float numbers have limited precision. While this is ok for most applications, when processing currency, you want to keep track of everything, from billions to cents.
  4. float numbers have states that are meaningless when dealing with currencies: what does it mean that a client deposited NaN dollars?
Stefano Sanfilippo
  • 32,265
  • 7
  • 79
  • 80
2

The floating point arithmetic has been a problem since long. That is why the usage BigDecimal is encouraged. To your question on how to use it properly, I've a simple example which can help you understand how BigDecimal can be used along with MathContext.

BigDecimal bd1 = new BigDecimal(0.13); // double value to BigDecimal
BigDecimal bd2 = new BigDecimal("0.21"); // String value to BigDecimal

MathContext mc = new MathContext(3, RoundingMode.HALF_EVEN); // first arg is the precision and the second is the RoundingMode.

BigDecimal bd3 = bd1.add(bd2, mc); // perform the addition with the context

System.out.println(bd3); // prints 0.340
Rahul
  • 44,383
  • 11
  • 84
  • 103
  • uhow to convert String into BigDecimal? – Tum Jan 31 '14 at 12:09
  • @Tum - BigDecimal has many overloaded constructors which takes in pretty much all primitive data types and also String as an argument. I edited the answer to reflect the same. – Rahul Jan 31 '14 at 12:11
0

Its because the conversion to binary is not even. Same as the fraction 1/3 becomes 0.33333333 when using decimal-system

The standard for floation numbers is called IEEE 754 and uses 32 bits

these 32 bits consist of the following parts

  • sign = 1 bit (0 = + ,, 1 = -)
  • exponent = 8 bits
  • mantissa = 23 bits

You could check this out by visit

http://www.binaryconvert.com/result_float.html?decimal=048046051052

so when convert 0.34 (as an example) to binary it becomes

 00111110 10101110 00010100 01111011

and when the computer converts it back the result in the decimal-fomrat is not exactly the same:

 00111110 10101110 00010100 01111011

 3.400000035762786865234375E-1
Björn Hallström
  • 3,775
  • 9
  • 39
  • 50