The fmod() Function

The Change Due Exercise, presented earlier this year, offered a solution that uses the fmod() function. That function is to real numbers as the modulus operator is to integers, though it’s not a straight-across comparison. That’s because floating point numbers can be imprecise.

As a review, the modulus operator % works with two integer values:

m = a % b;

Variable m is assigned the remainder of variable a divided by variable b. So 5 % 3 evaluates to 2.

For floating-point values, the fmod() function calculates the remainder of two values. Here’s the format:

fmod(a,b)

The fmod() function returns the remainder for variable a divided by variable b. Both a and b are float or double values, as is the value returned. The fmod() function requires that the math.h header be included.

In the Change Due Exercise, fmod() is presented as an alternative solution to truncate a floating-point value to 2 digits. To truncate, the second operator must be a power of 10; 0.01 truncates a value to two digits after the decimal. (0.01 is 10-2.) Then the result is subtracted from the original value for the Exercise’s solution.

The following code demonstrates how fmod() could be used to truncate a value to the second digit after the decimal:

#include <stdio.h>
#include <math.h>

int main()
{
    float a=123.45678;
    float r;

    r = fmod(a,0.01);
    printf("The remainder of %f and %f is %f\n",
            a,
            0.01,
            r);
    printf("%f is truncated to %f\n",
            a,
            a-r);

    return(0);
}

Here’s the output:

The remainder of 123.456779 and 0.010000 is 0.006779
123.456779 is truncated to 123.449997

Effectively, the result is 123.45. The value 123.449997 is within the degrees of precision, though it looks ugly when displayed.

The following code plows through powers of 10 from 0.00001 (10-5) to 10 (101), displaying the result of fmod() on the value 123.45678:

#include <stdio.h>
#include <math.h>

int main()
{
    float a=123.45678;
    float m=0.0001;
    
    for(m=0.00001;m<100;m*=10)
    {       
        printf("The remainder of %f and %f is %f\n",
                a,
                m,
                fmod(a,m));
    }

    return(0);
}

The for loop in Line 9 might get to 100 because of floating point precision, though it may not loop that high on your computer. Here’s the output:

The remainder of 123.456779 and 0.000010 is 0.000003
The remainder of 123.456779 and 0.000100 is 0.000083
The remainder of 123.456779 and 0.001000 is 0.000788
The remainder of 123.456779 and 0.010000 is 0.006782
The remainder of 123.456779 and 0.100000 is 0.056787
The remainder of 123.456779 and 1.000000 is 0.456787
The remainder of 123.456779 and 9.999999 is 3.456791
The remainder of 123.456779 and 99.999992 is 23.456787

The precision monster appears in the first line of output, showing 123.45678 as “123.456779.” The results are likewise fuzzy. For most mathematical operations, such results are tolerable, but for counting change at the cash register you might want to think about using integer values instead.

Leave a Reply