Reputation: 307
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
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
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