2

We are currently running some tests which involve ceiling numbers that have two decimal places. In order to achieve this, we are using Java's DecimalFormat.

However, the tests are getting strange results, particularly for the case when we wish to ceil up a '0.00xxx' number.

The following is the instance of the DecimalFormatter that is being used by the tests:

DecimalFormat decimalFormatter = new DecimalFormat("#########0.00");
    decimalFormatter.setRoundingMode(RoundingMode.CEILING);

This test works as expected, that is, it was ceiled correctly:

//The below asserts as expected
    @Test
    public void testDecimalFormatterRoundingDownOneDecimalPlace3()
    {
        String formatted = decimalFormatter.format(234.6000000000001);
        Assert.assertEquals("Unexpected formatted number", "234.61", formatted);
    }

However, this does not:

//junit.framework.ComparisonFailure: Unexpected formatted number 
//Expected :0.01
//Actual   :0.00

    @Test
    public void testSmallNumber()
    {
        double amount = 0.0000001;

        String formatted = decimalFormatter.format(amount);
        Assert.assertEquals("Unexpected formatted number", "0.01", formatted);
    }

Can you please explain why we are getting this behaviour. Thanks

EDIT:Another test as requested by comment. Still does not work.

//junit.framework.ComparisonFailure: null
//Expected :0.01
//Actual :0.00

@Test
public void testStackOverflow() throws Exception
{
double amount = 0.0000006;
String formatted = decimalFormatter.format(amount);
Assert.assertEquals("Unexpected formatted number", "0.01", formatted);
}

I noticed that for it to work, a number greater than 0 must be within the range of the pattern. Is this a bug or am I missing something?

Goaler444
  • 2,591
  • 6
  • 35
  • 53
  • +1 removed my answer it's wrong :( – Evgeniy Dorofeev Aug 27 '13 at 09:53
  • Try the same with 0.0000006. Whats the result? – T_01 Aug 27 '13 at 10:08
  • It's because rounding does only consider one digit beyond the requested format. The number is truncated to `0.000` and then rounded to `0.00`. I'm not sure how to change that behavior, though. – Bobby Aug 27 '13 at 10:14
  • @Bobby but the first test didnt consider the digit beyond the requested format. It read the last 1 and ceiled it.. =S – Goaler444 Aug 27 '13 at 10:16
  • Whoops, then I'm outta the loop... – Bobby Aug 27 '13 at 10:19
  • I've looked at this again, and [this simple and stupid test](http://pastebin.com/Y73SLedD) fuels my initial thought. Though, simply using `decimalFormatter.format(1 + amount)` instead yields the expected behavior. As long as the number is < 1 it seems to truncate one after a significant digit (was that English?). – Bobby Aug 28 '13 at 10:46
  • If I understood correctly, youve spotted the same thing I did, that is, a number greater than 0 must be within the range of the pattern for it to work. This is not the behaviour that is expected! – Goaler444 Aug 28 '13 at 11:34

1 Answers1

0

Looks like a bug. This code

    BigDecimal bd = new BigDecimal("0.0000001");
    bd = bd.setScale(2, RoundingMode.CEILING);
    System.out.println(bd);

produces correct result

0.01
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275