Is there a C or C++ function (or compiler flag) for the modulo/modulus/remainder operation (%
or %%
) for floating point numbers that would conform to the same mathematical standards in corner cases as the equivalent function/operator in Python or R does?
Normally, the operation should be something like
double modulus(x, y)
{
return x - (y * floor(x / y));
}
But there are many cases in which such simple operation would not yield the same result as Python and R.
These are some examples in Python and R, which do not match with either fmod
or remainder
or the macro above, even after adding -frounding-math
and -fsignaling-nans
:
1 % (-1/3) = -1/3
1 % (-1/2) = 0
2 % Inf = 2
(-2) % Inf = Inf
2 % (-Inf) = -Inf
(-2) % (-Inf) = -2
fmod
gives instead:
1 % (-1/3) = 0
1 % (-1/2) = 0
2 % (Inf) = 2
-2 % (Inf) = -2
2 % (-Inf) = 2
-2 % (-Inf) = -2
I figured out some additional conditions could be added in order to mimic the results:
double modulus(x, y)
{
if (isinf(x)) {
return NAN;
}
if (isinf(y)) {
if (isinf(x))
return NAN;
else {
if (x == 0 || isnan(x) || (x > 0) == (y > 0))
return x;
else
return y;
}
}
return x - (y * floor(x / y));
}
But even then it still doesn't work correctly for the cases in which -1 < y < 0
, and I don't even know if I'm still missing more corner cases.
How can I get a function that would give the exact same results in C/C++ as the modulus operators from Python and R?