Canada decided to withdraw penny coin. In order to keep everything going smoothly and fair they also specified rules for rounding. Rules that are not readily available in any programming language.
In time before rounding functions you would round stuff by multiplying by 100 (in case of pennies) and adding 0.5. You would truncate resulting number and divide it with 100 thus abusing implicit rounding when stuff gets converted to int. Something like this:
int pennies = (int)(value * 100 + 0.5);
return pennies / 100.0;
With nickel rounding we shall use almost same algorithm:
private static Decimal RoundPenny(Decimal value) {
var pennies = Math.Round(value * 100, 0);
var nickels = Math.Truncate((pennies + 2) / 5);
var roundedPennies = nickels * 5;
return roundedPennies / 100;
}
First we just get a number of pennies. Then we increase number by two pennies (half of nickel) and divide everything by one nickel. Truncating result gives us number of nickel coins that we need for a given penny count. Multiplication by five converts everything back to pennies and final division by 100 ensures that dollars are returned.
Code is here.
PS: Yes, you can write this more concise but I think that this makes example much more readable. Concise example would be:
return Math.Round(value * 20, 0) / 20;