Hi.
I have the following C code.
int main(int argc, char* argv[])
{
// float yInit, yInc, yNext, y;
double yInit, yInc, yNext, y;
double yMin, yMax, yMinimum=0.1, yMaximum=10.9;
yMin = log10(yMinimum);
yMax = log10(yMaximum);
printf(“Min: %lg Max: %lg log10(Min): %lg log10(Max): %lg\n”, yMinimum,
yMaximum, yMin, yMax);
yInit = pow(10, floor(yMin));
yInc = yInit;
yNext = yInit * 10;
y = yInit;
printf(“Init: %lg Inc: %lg Next: %lg\n”, yInit, yInc, yNext);
for (y=yInit; y<=yMaximum; y+=yInc) {
if (y<yMinimum) {
continue;
}
if (y>=yNext) {
yInc *= 10;
yNext *= 10;
}
printf("%g\n", y);
}
return 0;
}
When I define y and yNext as floats, the code works. When I define y and
yNext as doubles, it doesn’t. Why?
I have tried this in two different compilers (Watcom c in QNX 4 and Visual
C++ in Windows 95), with the same results.
I would expect the statement (y>=yNext) to be true when y=1.0 and yNext=1.0.
This is not what happens.
Any Ideas?
Thanks a lot.
Augie
Have you included math.h
“Augie Henriques” <henriques@neca.com> wrote in message
news:8td6up$fuv$1@inn.qnx.com…
Hi.
I have the following C code.
int main(int argc, char* argv[])
{
// float yInit, yInc, yNext, y;
double yInit, yInc, yNext, y;
double yMin, yMax, yMinimum=0.1, yMaximum=10.9;
yMin = log10(yMinimum);
yMax = log10(yMaximum);
printf(“Min: %lg Max: %lg log10(Min): %lg log10(Max): %lg\n”,
yMinimum,
yMaximum, yMin, yMax);
yInit = pow(10, floor(yMin));
yInc = yInit;
yNext = yInit * 10;
y = yInit;
printf(“Init: %lg Inc: %lg Next: %lg\n”, yInit, yInc, yNext);
for (y=yInit; y<=yMaximum; y+=yInc) {
if (y<yMinimum) {
continue;
}
if (y>=yNext) {
yInc *= 10;
yNext *= 10;
}
printf("%g\n", y);
}
return 0;
}
When I define y and yNext as floats, the code works. When I define y and
yNext as doubles, it doesn’t. Why?
In all your print statement change %lg to %.20lg, you will see that what you
though
were .1 values for example are actually .1000…0001 !!! When dealing with
float or double relying on an == comparaison is very dangerous. The
if ( y>=yNext ) statement on the 10th iteration will success with float and
fail
with double!! The problem is that yNext is a result of one operation ( *10)
and y is the resolut of 10 additions, thus because of precion error, when
you thing y == yNext it’s actually not.
Now I don’t know enough about the IEEE representation nor the FPU
implementation
to explain exactly why that is. But the sad fact is do not rely on a == to
work with
float or double.
This quick patch will make your program work, in this perticural case…
if ( y >= ( yNext - .00000001) )
I have tried this in two different compilers (Watcom c in QNX 4 and Visual
C++ in Windows 95), with the same results.
I would expect the statement (y>=yNext) to be true when y=1.0 and
yNext=1.0.
This is not what happens.
Any Ideas?
Thanks a lot.
Augie
Seems to be a problem of accuracy. Change line
if (y>=yNext) {
into
#define EPSILON 0.000001
if (y+EPSILON >= yNext) {
Reason: double type is of 15-16 digits of precision, float only 5-6. So 10
times .1 is 1.0 in float but 0.999999999999 perhaps in double.
/martin
Augie Henriques <henriques@neca.com> schrieb in im Newsbeitrag:
8td6up$fuv$1@inn.qnx.com…
Hi.
I have the following C code.
int main(int argc, char* argv[])
{
// float yInit, yInc, yNext, y;
double yInit, yInc, yNext, y;
double yMin, yMax, yMinimum=0.1, yMaximum=10.9;
yMin = log10(yMinimum);
yMax = log10(yMaximum);
printf(“Min: %lg Max: %lg log10(Min): %lg log10(Max): %lg\n”,
yMinimum,
yMaximum, yMin, yMax);
yInit = pow(10, floor(yMin));
yInc = yInit;
yNext = yInit * 10;
y = yInit;
printf(“Init: %lg Inc: %lg Next: %lg\n”, yInit, yInc, yNext);
for (y=yInit; y<=yMaximum; y+=yInc) {
if (y<yMinimum) {
continue;
}
if (y>=yNext) {
yInc *= 10;
yNext *= 10;
}
printf("%g\n", y);
}
return 0;
}
When I define y and yNext as floats, the code works. When I define y and
yNext as doubles, it doesn’t. Why?
I have tried this in two different compilers (Watcom c in QNX 4 and Visual
C++ in Windows 95), with the same results.
I would expect the statement (y>=yNext) to be true when y=1.0 and
yNext=1.0.
This is not what happens.
Any Ideas?
Thanks a lot.
Augie