Niels Dybdahl said:
Do you have details on the system that returns 6700 ? (Hardware, OS,
Compiler).
Doing the calculation in 32 bit floats would probably return 6700, while
using 64 bit or 80 bit would return 6699.
Yes, you can typically only be sure of 7-digits of precision with
32-bit floating point values.
In general, addition and subtraction of numbers that differ by several
orders of magnitude should be a flag to watch out for precision errors
like the one the OP is having. It is usually possible to formulate
the original expression in a way that makes the precision problem more
tractable .. for example, if the numbers in the expression above are
really literals, the OP could remove the trivial integer division from
the problem to give:
double A = 6700.0 - ceil(0.1/365.25);
which will yield 6699 on a wider range of architectures.
Of course the problem is not likely to be so simple, but general
techniques can often be devised if you can say some things about the
arguments in advance. For example,
double func(double arg1, double arg2, double divisor) {
// assume arg1, arg2 non-negative and divisor > 1
double tmp1=floor(arg1/divisor);
double tmp2=floor(arg2/divisor);
double residue=(arg1-tmp1*divisor) - (arg2-tmp2*divisor);
return tmp1 - tmp2 - (residue<0) ? 1 : 0;
}
will carry out the schematic calculation from the OP's example,
yielding results that are somewhat less prone to precision error. The
key point is that the values that are subtracted are guaranteed to be
closer in magnitude than the original arguments. I expect there is a
more efficient way to write it, but it was just a quick example ...
also, sometimes efficiency must ultimately be sacrificed for the sake
of precision.
Check out a book like "The Art of Scientific Computing" for more info.
HTH, Dave Moore