gab
gab

Reputation: 307

How do I check if a double is divisible by another double?

I have two arbitrary doubles. The code should only continue if the division of one double by the other double is an integer, so I can't really cast the result to a double. I could do a normal double division and then check if the result is inside a tiny range of specified integers, but that seems pretty messy.

Does someone know a better solution?

Upvotes: 2

Views: 1035

Answers (2)

PaulMurrayCbr
PaulMurrayCbr

Reputation: 1260

Check if the mantissa of the larger is divisive by the mantissa of the smaller by the usual integer means (take the gcd).

Upvotes: 0

Jan Schultke
Jan Schultke

Reputation: 39773

To test if one number is evenly divisible by another number, you can use std::fmod. std::fmod returns the remainder of a division. If the remainder is zero, then these numbers must be evenly divisible.

#include <cmath>
#include <limits>

constexpr double epsilon = std::numeric_limits<double>::epsilon();

constexpr bool divisible(double dividend, double divisor) {
    // exact match using "== 0" usually isn't safe
    return std::fabs(std::fmod(dividend, divisor)) < epsilon;
}

There are situations where we can't use std::fmod, such as in a constant expression (until C++23). As a workaround, we can write the following:

#include <cstdint>

constexpr bool divisible(double dividend, double divisor) {
    double quotient = dividend / divisor;
    double quotient_fraction = quotient - static_cast<std::intmax_t>(quotient);
    return quotient_fraction > -epsilon && quotient_fraction < epsilon;
}

Here, we compute the quotient, and then try to figure out if the quotient has a fractional part. See Best way of checking if a floating point is an integer for alternative solutions.

Upvotes: 5

Related Questions