What's wrong with this

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