fmod telling me fractional part of 1 is 1

122 views Asked by At

I'm trying to check if a double variable p is approximately equal to an integer. At some point in my code I have

double ip;
cout << setprecision(15) << abs(p) << " " << modf(abs(p), &ip) << endl;

And for a given run I get the printout

1 1

This seems to say that the fractional part of 1 is 1, am I missing something here or could there be some roundoff problem etc?

Note: I'm not including the whole code since the origin of p is complicated and I'm just asking if this is a familiar issue

2

There are 2 answers

0
Mike Seymour On BEST ANSWER

could there be some roundoff problem etc?

There certainly could. If the value is very slightly less than 1, then both its value and its fractional part could be rounded to 1 when displayed.

the origin of p is complicated

Then it's very likely not to be an exact round number.

2
Deduplicator On

You are testing a nearly-1-value, so precision of 15 is not enough to describe it unambiguously.

This code shows your problem clearly:

#include <iostream>
#include <iomanip>
#include <cmath>
#include <limits>
using namespace std;

int main() {
    double ip, d = nextafter(1., .0); // Get a double just smaller than 1
    const auto mp = std::numeric_limits<double>::max_digits10;
    cout << 15 << ": " << setprecision(15)
        << abs(d) << " " << modf(abs(d), &ip) << '\n';
    cout << mp << ": " << setprecision(mp)
        << abs(d) << " " << modf(abs(d), &ip) << '\n';
}

On coliru: http://coliru.stacked-crooked.com/a/e00ded79c1727299

15: 1 1
17: 0.99999999999999989 0.99999999999999989