jorgen
jorgen

Reputation: 3593

fmod telling me fractional part of 1 is 1

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

Upvotes: 1

Views: 145

Answers (2)

Deduplicator
Deduplicator

Reputation: 45654

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

Upvotes: 2

Mike Seymour
Mike Seymour

Reputation: 254461

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.

Upvotes: 2

Related Questions