0

I have tried a simple java program to round off the Float value

float value = 0.525f;
System.out.println(Math.round(value * 100.0d) / 100.0f)

Getting Output is - 0.52 But expected is - 0.53

When I debug the value of float value variable it is showing me 0.5249999761581421 something like. I think because of only this reason it is not rounding correctly.

Please help me if anyone knows how to round the float value up to two decimal places.

Vijay Shegokar
  • 2,492
  • 1
  • 20
  • 30

1 Answers1

2

When converting 0.525f into a double (which implicitely happens in your calculation), 0.5249999761581421 is the nearest double representation. This number will then get rounded down.

Another issue is that your expression always rounds down (as you just cut off all but the first two decimal places).

Java has built-in support for rounding numbers in the BigDecimal class.
For rounding such a number, use:

String s = String.valueOf(0.525f); // results in "0.525"
BigDecimal rounded = new BigDecimal(s).setScale(2, RoundingMode.HALF_UP);
System.out.println(rounded);

which results in 0.53.

Also note that are different ways of rounding numbers (see Javadoc for RoundingMode).

Peter Walser
  • 15,208
  • 4
  • 51
  • 78
  • That String.valueOf will probably result in "0.5249999761581421". Better would be to just use the string "0.525" – David Zimmerman Jul 18 '19 at 18:30
  • @DavidZimmerman `String.valueOf(0.525f)` results in `0.525`. This might not work for any numbers though, as the number literal in the code will be translated to the nearest float (or double) value. If the input is text indeed, then taking the string constructor of BigDecimal is the way to go, correct. – Peter Walser Jul 19 '19 at 12:15
  • @PeterWalser: Java’s default conversion of floating-point to string uses the [fewest significant digits that uniquely distinguish the floating-point number](https://stackoverflow.com/a/56905831/298225). Because of this, when a decimal numeral of at most 9 or 17 significant digits is converted to `float` or `double`, respectively, and converted back, the result is equal to the number of the original numeral. The first conversion produces the nearest floating-point number, and, for the second conversion, the original number is the one that uniquely distinguishes the floating-point number. – Eric Postpischil Jul 27 '19 at 12:11
  • The limits of 9 and 17 are because, beyond that many digits, the decimal numerals may be closer together than the consecutive `float` or `double` numbers, so there may be several decimal numerals between the floating-point numbers, so the decimal numeral that results, when converted, in a particular floating-point number is not necessarily the one that uniquely distinguishes the floating-point number. Of course, converting from a numeral in the source code to a floating-point number and then back to a string is wasteful, so, as you note, one ought to simply pass a string to `BigDecimal`. – Eric Postpischil Jul 27 '19 at 12:14
  • However, note that `.525f` does not produce 0.5249999761581421 when converted to `double` (or to `float` or to `float` and then to `double`). It produces 0.52499997615814208984375. While this may seem like a tiny difference, tiny changes are what cause so much confusion with floating-point arithmetic, so it is necessary to be exact. – Eric Postpischil Jul 27 '19 at 12:16