Background
Consider the validation of three doubles low
, width
and high
such that the following three rules hold true:
low < high
;width > 0
; andwidth
fits into(high - low)
"exactly" a whole number of times.
Essentially, the three values should specify a range that is to be split up into a certain number of bins, each of "exactly" equal width, with no part of the range unnaccounted for.
For example:
(A) low = -0.5
, width = 0.005
and high = 0.5
would specify a range with a valid bin width, since "exactly" 200 full bins can be created, whereas
(B) low = -0.5
, width = 0.275
and high = 0.5
would specify a range with an invalid bin width, since 3 full bins could be created but part of the range is not covered by those bins.
The Problem
What is the best way approach the third validation rule, given the floating-point nature of doubles?
My first naive attempt consisted of:
fmod( high - low, width ) == 0.0
but unfortunately fmod returns 0.005 for example (A) - my debugger tells me that the double of 0.005 actually holds the value of 0.0050000000000000001
.
Should I be home-brewing my own solution to include tolerances, or is there a more elegant solution to this problem?
This is what I have currently:
bool valid(double range, double width, double tolerance = 0.000000001)
{
assert(width > 0 && range > 0);
while( range > 0 && range > tolerance )
{
range -= width;
}
return abs(range) <= tolerance;
}
Note the complete and utter arbitrariness of the default value of tolerance ...