6

I have written this code and run anonymously, and got some strange results which seem to indicate a bug in Math.Round(decimal) - look like an overflow:

Decimal d  = 1000000000.0;
Decimal dd = 10000000000.0;
Decimal ddd = 100000000000000.0;
System.debug('d='+d);
System.debug('dd='+dd);
System.debug('ddd='+ddd);

System.debug('round d='+Math.round(d));
System.debug('round dd='+Math.round(dd));
System.debug('round ddd='+Math.round(ddd));

Results are:

d=1000000000.0
dd=10000000000.0
ddd=100000000000000.0

round d=1000000000
round dd=1410065408
round ddd=276447232

As you see, it's wrong from dd onwards.

Is this definitely a bug, or am I misunderstanding something? If it is a bug, has anyone else found this? Is there a workaround?

1
  • In line 6, you have System.debug('dd=') but in your results you have ddd= FYI Commented Dec 15, 2015 at 16:38

2 Answers 2

6

You can use Math.roundToLong instead, as Math.round returns an Integer

Decimal d  = 1000000000.0;
Decimal dd = 10000000000.0;
Decimal ddd = 100000000000000.0;
System.debug('d='+d);
System.debug('dd='+dd);
System.debug('ddd='+ddd);

System.debug('round d='+Math.roundToLong(d));
System.debug('round dd='+Math.roundToLong(dd));
System.debug('round ddd='+Math.roundToLong(ddd));

This gives the results you would expect

d=1000000000.0
dd=10000000000.0
ddd=100000000000000.0

round d=1000000000
round dd=10000000000
round ddd=100000000000000
5

This isn't well defined behavior. Math.round returns an Integer, which has a maximum value of 2147483647. dd and ddd both exceed this cap - this, along with the fact that Decimal has no explicit upper bound, speaks to this behavior.

If you try this, with a Double that does have an explicit upper bound of (2^63) - 1, a MathException for Integer overflow is thrown, as expected:

Double dbl = 100000000000000.0;
System.debug(Math.round(dbl));

System.MathException: Integer overflow: 100000000000000

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .