A Penny for Your Thoughts

If you’re a Canadian developer writing POS software, you have probably implemented a Penny Rounding algorithm to deal with the removal of the Canadian Penny from circulation. ¬†An issue with writing such software is ensuring it works with a variety of regional settings, especially if the target machines are not locked down, or require support for multiple languages.

My implementation is as follows:

function PennyRound(Value :Currency) :Currency;
{
Implements the Canadian Penny Rounding algorithm
to round to a 5 cent value.
}

var
  sTemp :string;
  LastDigit :Char;
begin
  sTemp := FloatToStrF(Value,TFloatFormat.ffFixed,15,2);
  LastDigit := sTemp[Length(sTemp)];

  if CharInSet(LastDigit,['2','7']) then
  begin  //round down by subtracting 0.02
    Result := Value - 0.02;
  end
  else
  if CharInSet(LastDigit,['1','6']) then
  begin  //round down by subtracting 0.01
    Result := Value - 0.01;
  end
  else
  if CharInSet(LastDigit,['4','9']) then
  begin  //round up by adding 0.01
    Result := Value + 0.01;
  end
  else
  if CharInSet(LastDigit,['3','8']) then
  begin  //round up by adding 0.02
    Result := Value + 0.02;
  end
  else  //value is already in 5 cent increments
  if CharInSet(LastDigit,['5','0']) then
  begin
    Result := Value;
  end;
end;

Anyone have a better implementation?


Leave a Reply