Re: How to determine if double contains an integer value?
Jiang wrote:
Greg Herlihy wrote:
Martin Eisenberg wrote:
Assigning a floating point value to an int variable is not the purpose
of the routine we have been asked to write - testing whether a floating
point value is exactly divisible by 1.0 - on the other hand - is the
problem we need to solve. And as it happens there are (at least) two
standard functions that can provide the needed answer - either of which
will do so reliably.
I am not sure they are reliable for decimal floating literals or not,
and I tested your method.
$ cat fmod.cpp
#include <cmath>
#include <iostream>
int main()
{
double d = 1.0000000000000001;
if(std::fmod(d,1.0) == 0.0){
std::cout << "exact division\n";
}else{
std::cout << "not exact division\n";
}
}
$ ./fmod
exact division
$
Is it the problem of double value representation? Or, the comprison
is not reliable?
The program is producing the correct result given the values and the
floating point types used in its calculations. Now if the programmer is
expecting a different result, then the programmer is simply expecting a
greater degree of resolution than this program's double type can
provide. In particular, two floating point values must differ by at
least numeric_limits<double>::epsilon in order to ensure that the
compiler will recognize them as distinct double values. By the same
token, any two floating values that differ by less than epsilon are
likely to resolve to the same double value - as this programm
demonstrates.
The reason that this program may be reporting the "wrong" result is
simply that the difference between 1.0000000000000001 and 1.0 is only
1.0e-16 - or less than half of 2.22e-16 (which is the value of a
double's epsilon on most computers). Therefore this program resolves
1.0000000000000001 and 1.0 to same double value: 1.0. And 1.0 is an
integer value.
Now it might be helpful were the compiler to warn whenever the
specified value of a floating point literal exceeds the precision of
its type - but a C++ compiler is not obligated to do so. As long as the
specified value lies within (and not beyond) the range of representable
values for the type, the compiler is free to round to the closest
larger or the closest smaller value (in an implementation-defined
manner).
So without much in the way of help to be expected from the compiler in
this kind of situation, it is really up to the programmer to use
numeric_limits to check that the precision of a program's floating
point calculations is at least able to match the degree of precision
expected from them.
Greg
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]