Math.floor always rounds down, Math.ceil always rounds up. Using Math.round uses half-even rounding mode, so you can simply say:
Integer result = Math.round(96.7);
Half-even means that if a value is exactly 0.5, it rounds to the nearest even number (96.5 rounds to 96, 97.5 rounds to 98). This is the most "fair" statistically speaking, but you need to follow other rules, you can:
Decimal value = 96.7;
Integer result = value.round(RoundingMode.HALF_UP);
Which would round up on 0.5 or higher, for example. You can read about all the rounding types here.
Answer from sfdcfox on Stack ExchangeVideos
I don't think it gets more concise than this:
Decimal toround = 3.14159265;
Decimal rounded = toround.setScale(2);
system.debug(rounded);
What's nice about this one is you can use the setScale overload that lets you specify the rounding mode you want to use.
Decimal toround = 3.14159265;
Decimal rounded = toRound.setScale(2, RoundingMode.HALF_UP);
system.debug(rounded);
In this case - I think you'll want the HALF_UP rounding mode. It's the traditional round to nearest, but round .5 up.
Decimal toRound = 3.1445;
Decimal rounded = toRound.setScale(2, RoundingMode.CEILING);
system.debug(rounded);
3.15
toRound.setScale(2, RoundingMode.HALF_UP);
will not return 3.15 from 3.1445.
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
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
Who needs an if statement:
- 1.94 + .05 = 1.99 round up to 2.0 - .05 = 1.95
- 1.95 + .05 = 2.0 Round up to 2.0 - .05 = 1.95 - I ran a test to prove this one out
- 1.96 + .05 = 2.01 round up to 3.0 - .05 = 2.95
- 3.35 + .05 = 3.4 round up to 4.0 - .05 = 3.95
In other words:
//Assume your price variable is called price
price += .05;
price = price.round(System.RoundingMode.UP);
price += -.05;
Boredom Update
A gentleman I know pointed out a while ago that you achieve the "normal" rounding behavior in a pretty simple way:
Decimal value += .5
Integer roundedValue = (Integer) value;
I just adopted that methodology to fit your case. The differences are
- you always want to round up
- your "half-way" point is .95 as opposed to .5.
That is not a rounding mode supported by the Decimal class, but it's easy enough to implement in logic.
What you need to do is truncate the value (chop off the fractional amount) and then subtract the result from the value so you get back just the fraction. Then you can easily write logic comparing the fraction to 0.95.
The way to get this fractional value, assuming your dollar value is a Decimal value (as it should be), is to call
myFraction = myDecimal.round(System.RoundingMode.DOWN))
You can implement your logic from there to make adjustments to the final price.