0

I am experiencing a very strange behaviour when i am trying to print float number with more decimal points.

Float price = Float.valueOf("1602.72");
System.out.println(price); //prints 1602.72
outputValue =   String.format("%.6f", price);
System.out.println(outputValue); //prints 1602.719971

I have also used below code but getting the same result

DecimalFormat df = new DecimalFormat("0.000000");
System.out.println(df.format(price)); //prints 1602.719971

I am expecting outputValue as 1602.720000 (6 digits after decimal with extra zeros)

vahdet
  • 6,357
  • 9
  • 51
  • 106
user812142
  • 163
  • 2
  • 17
  • So, there is no method to achieve trailing zeros? – user812142 Mar 08 '19 at 11:48
  • Closely related to this even if it is tagged specifically for android: https://stackoverflow.com/q/35673034/4636715 So, consider using [`BigDecimal`](https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html). – vahdet Mar 08 '19 at 11:51
  • So there is no method to do it in float and decimal. I am now appending 0's to string. Thanks – user812142 Mar 08 '19 at 11:59

3 Answers3

1

Never use floats or doubles for prices, floats and doubles are approximations, see: IEEE_754.

Have a look at BigDecimal instead.

Edit to be exact: use floats or doubles to represents decimals is an approximation.

6pi
  • 387
  • 2
  • 11
  • 2
    **All** numerical arithmetic at best approximates real arithmetic. It is incorrect to suggest that BigDecimal is not an approximation while binary floating-point is. For example, BigDecimal cannot represent one-third. Correct statements of the differences are that BigDecimal uses a decimal base, and hence can exactly represent decimal numerals, and that BigDecimal provides arbitrary precision rather than IEEE-754’s fixed precision. – Eric Postpischil Mar 08 '19 at 12:13
  • 1
    BigDecimal represents decimal numbers, not real one, so it's not an approximation. The question is about price which is also decimal, so we can exactly represent price with BigDecimal. How much is this sandwich? 6π$ :D So, yes representing real with BigDecimal will be an approximation, but my answer is context oriented, natural language is context oriented… – 6pi Mar 08 '19 at 12:35
  • If BigDecimal is not on approximation because it represents decimal numbers, then `float` and `double` are not approximations because they represent binary numbers. BigDecimal is subject to errors the same as binary floating-point is: As noted, dividing 1 by 3 in BigDecimals produces result that is not mathematically correct. That means, if a merchant offers a buy-two-get-one-free deal, BigDecimal cannot represent the effective unit price. – Eric Postpischil Mar 08 '19 at 12:40
  • Ok, but the author of the question wants to represent price! So, decimals. – 6pi Mar 08 '19 at 12:41
  • 1
    As noted with my example, prices are not always in decimal. Nor does decimal automatically solve all problems in currency calculations. It is misleading to suggest that binary floating-point arithmetic is merely an approximation while BigDecimal is not. They are **both** approximations, but they are **different** approximations. Since your answer suggests one is an approximation, and the other is not, it is misleading. – Eric Postpischil Mar 08 '19 at 12:43
  • ok, you are right, but a few pedantic :). But, maths are pedantics… – 6pi Mar 08 '19 at 12:54
1

A float is a binary representation of a number ( 1 / 2 ^^ ? )
like:

1/2^1 = 0.5, 
1/2^2 = 0.25, 
1/2^3 = 0.125, 
1/2^4 = 0.0625, ...  

The result renders from an addition of this binary numbers to find the closest match.

CJCrafter
  • 75
  • 1
  • 11
m4tt
  • 26
  • 4
0

That happens because floating point values are often imprecise for decimal fractions.

Basically, since floats are represented using negative powers of 2, some decimal values are very hard to represent accurately (e.g.: how do you write 0.3 as a sum of powers of two?).

You can try Float.valueOf("1602.720000") or Double.valueOf("1602.72") (better), but those will probably have the same issues.

Refer to this answer for a more detailed explanation.

GBrandt
  • 685
  • 4
  • 11