Mathematical “mod” versus Delphi “mod”.

Last week I discovered that I had “assumed” that the mod operator in Delphi was the same as the mod operator that I’ve always used in Mathematics.

For most of the algorithms I use, I am dealing with Positive Integers – and there is no problem there. Thus I didn’t encounter the problem till I was doing some unit testing with Calendar Functions based on “Reference Dates” and using mod 7 to get the Day of Week. As soon as I started testing dates in the BC/BCE Eras I was getting the wrong values – because my Reference Dates (which are just Integers) had gone Negative.

I expect -1 mod 7 to be 6 since in Mathematics -1 mod 7 is modularly congruent to 6 mod 7, 13 mod 7, etc.

Delphi is doing Remainder rather than modular congruence 🙁 So we also get the mod <negative> works fine for negative values but isn’t equivalent for positive.

See the table that follows – Delphi Values are copied from  a simple For Loop done in  in Delphi XE2 and the Excel Row is using the MOD Function in Excel 2013. Notice Excel does get things right.

mod problem

Notice how the pattern repeats in the Maths version (and the Excel version) so that it continues on to infinity in both directions – this doesn’t happen with the Delphi version 🙁

So I needed a replacement mod – and for now I am using the following, which is simple and works (so all my Unit Tests now pass) and I am using as an Inline Function.

function IntMod (const X, Y: Integer): Integer;
begin
    Result := (X mod Y + Y) mod Y;
end;

And a similar routine for Int64 values.

Note: This is not just a Delphi issue – seems C# has a similar issue with the “%” operator, so will investigate that further tomorrow 🙂

For C# the IntMod Function would be:

          public static int IntMod (int X, int Y)
          {
               return (X % Y + Y) % Y;
          }

About esbglenn

Software Developer working at our Family owned business, ESB Consultancy, which is located in Kalgoorlie-Boulder, in the Eastern Goldfields of Western Australia.
This entry was posted in Math in Delphi and tagged , , , . Bookmark the permalink.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.