I'm implementing a Q31.32 fixed-point numeric type based on System.Int64 in C#. Right now I'm trying to get the modulo operation correctly (%).
All implementations of fixed-point arithmetic I've seen define Qm.n modulo simply in terms of integer modulo, i.e. the modulo of two Qm.n numbers is the modulo of their underlying integer representation. This works in the general case but fails in two specific cases:
x % y
throws anOverflowException
ifx == Int64.MinValue
andy == -1
. I can easily deal with this with an if statement and returning 0 in this case, although this is strange behavior (andunchecked
is of no help here).x % y
incorrectly returns 0 for some small values ofx
andy
. For example, if the integer representations ofx
andy
are-413
and59
(decimal: ~-0.000000096159 and ~0,000000013737), the modulo is0
(decimal: 0) while the modulo of their decimal value is (according to System.Decimal) ~-0.000000013737. This error is about 60 times greater than the maximum precision of the type (2^-32), so it cannot be considered a rounding error.
What is the cause of this last error and is there anything I can do to obtain better accuracy?