c++cmath

fmod or not fmod?


I dug into old code, and saw a function like this:

inline double mod(double x, double y)
{
    return x-y*floor(x/y);
}

is fmod its full equivalent, or have I missed something?


Solution

  • No, the above routine it is not the same as fmod(). Specifically it is different for situations where one argument is negative.

    Your routine does a floor(), which rounds down to the next integer. With fmod() the rounding is like trunc(), i.e. towards zero.

    Here's an extract from the Open Group standard (here):

    These functions shall return the value x- i* y, for some integer i such that, if y is non-zero, the result has the same sign as x and magnitude less than the magnitude of y.

    If the correct value would cause underflow, and is not representable, a range error may occur, and either 0.0 (if supported), or an implementation-defined value shall be returned.

    If x or y is NaN, a NaN shall be returned

    If y is zero, a domain error shall occur, and either a NaN (if supported), or an implementation-defined value shall be returned.

    If x is infinite, a domain error shall occur, and either a NaN (if supported), or an implementation-defined value shall be returned.

    If x is ±0 and y is not zero, ±0 shall be returned.

    If x is not infinite and y is±Inf, x shall be returned.

    If the correct value would cause underflow, and is representable, a range error may occur and the correct value shall be returned.

    That's difficult to understand, but the word 'magnitude' in the first paragraph illustrates the rounding is towards zero.

    Here's an extract from the much more helpful documentation for the GCC library:

    These functions compute the remainder from the division of numerator by denominator. Specifically, the return value is numerator - n * denominator, where n is the quotient of numerator divided by denominator, rounded towards zero to an integer. Thus, fmod (6.5, 2.3) returns 1.9, which is 6.5 minus 4.6.