eyt*
Dec 03, 2011

Rounding numbers with Java’s NumberFormat...

Take a look at the following numbers and round them to the nearest whole number:

  1. 2
  2. 2.1
  3. 2.2
  4. 2.3
  5. 2.4
  6. 2.49
  7. 2.5
  8. 2.51
  9. 2.6
  10. 2.7
  11. 2.8
  12. 2.9
  13. 3

I’m pretty confident that you will get the same answers as my 4th grader, which is that the numbers from 1-6 result in a 2 and 7 onwards results in 3, right? Well, given the following code though, you’d be surprised:

  1. import java.text.DecimalFormat;
  2. import java.text.NumberFormat;
  3. public class test {
  4.   public static void main( String [] args ) {
  5.      double [] values = new double[] { 2, 2.1, 2.2, 2.3, 2.4, 2.49, 2.5, 2.51, 2.6, 2.7, 2.8, 2.9, 3.0 };
  6.      final NumberFormat format = new DecimalFormat( "#" );
  7.      for ( double d : values ) {
  8.         System.out.println( d + ": " + format.format( d ) );
  9.      }
  10.   }
  11. }

Your surprise would come from the fact that the 2.5 rounds down to 2. Why? Well, reading the DecimalFormat javadocs closely, you will notice that the default rounding policy is HALF_EVEN, in which the above behaviour is explained. To change that, simply use format.setRoundingMode( RoundingMode.HALF_UP ); or one of the other policies available in the rounding mode.

Why this is the default behaviour is puzzling to me, but I’ll just add it to the list, which includes the Math.abs() handling of Integer.MIN_VALUE and non-thread-safe SimpleDateFormat [Link removed] (which, for the record, I do not believe that the code suggested in that blog post is guaranteed to be thread-safe either... since the DateFormat class is declared to be non-threadsafe also).

Filed In

Navigation

eyt*