M
Michael Mair
Hi there,
actually, I have posted the same question in g.g.help.
As there were no answers, I am still not sure whether this
is a bug or only something open to the compiler that is
seemingly inconsistent or whether my understanding of C
is not complete enough.
I would appreciate answers or pointers to answers very much.
Cheers,
Michael
---------original post to g.g.help-----------------------
for a C course I gave the students the task to compute
FLT_EPSILON, DBL_EPSILON and LDBL_EPSILON.
We are using gcc 3.2 and gcc 3.4 on Linux machines.
The following
epsilon_float = 1.0F;
while (1.0 + eps_float != 1.0)
eps_float /= 2.0;
eps_float *= 2.0;
will give the students not FLT_EPSILON, but LDBL_EPSILON
in float precision, as the expressions in the condition for
while are evaluated in long double precision.
Now we apply the necessary type casts
epsilon_float = 1.0F;
while ((float)(1.0 + eps_float) != (float)1.0)
eps_float /= 2.0;
eps_float *= 2.0;
and everything works fine.
Right. Up to now, everything is fine and completely to my
understanding. But if I try the same with doubles, I get
LDBL_EPSILON even with the cast. (Example provided below)
Is this a problem in gcc or am I missing some finer points
of C? I tried RTFM and STFW but probably looked in the wrong
places.
It would be great if someone could tell me what is going
wrong or point me in the right direction.
Cheers,
Michael
gcc -Wall -std=c99 -pedantic castepsilon.c
--------------------------castepsilon.c-------------------
#include <stdio.h>
#include <float.h>
int main (void)
{
float eps_float = 1.0F;
double eps_double_test = 1.0, eps_double = 1.0;
long double eps_long_double = 1.0L;
// find FlT_EPSILON
while ((float)(1.0 + eps_float) != (float)1.0)
eps_float /= 2.0;
eps_float *= 2.0;
// find DBL_EPSILON
while ((double)(1.0 + eps_double_test) != (double)1.0)
eps_double_test /= 2.0;
eps_double_test *= 2.0;
// alternative way
for ( double test=1.0 + eps_double; test != (double)1.0;
test=1.0 + eps_double)
eps_double /= 2.0;
eps_double *= 2.0;
// find LDBL_EPSILON
while ((long double)(1.0 + eps_long_double) != (long double)1.0)
eps_long_double /= 2.0;
eps_long_double *= 2.0;
// Output
printf("Epsilon is --");
printf(" exact val\n");
printf(" - for float : %8.7g -- %8.7g\n",
eps_float, FLT_EPSILON);
printf(" - for double (1) : %17.16g -- %17.16g\n",
eps_double_test, DBL_EPSILON);
printf(" - for double (2) : %17.16g -- %17.16g\n",
eps_double, DBL_EPSILON);
printf(" - for long double: %20.19Lg -- %20.19Lg\n\n",
eps_long_double, LDBL_EPSILON);
return(0);
}
-------------------------------------------------------------------
mairml@cip20:~/C/test> ./a.out
Epsilon is -- exact value --
- for float : 1.192093e-07 -- 1.192093e-07
- for double (1) : 1.084202172485504e-19 -- 2.220446049250313e-16
- for double (2) : 2.220446049250313e-16 -- 2.220446049250313e-16
- for long double: 1.084202172485504434e-19 -- 1.084202172485504434e-19
actually, I have posted the same question in g.g.help.
As there were no answers, I am still not sure whether this
is a bug or only something open to the compiler that is
seemingly inconsistent or whether my understanding of C
is not complete enough.
I would appreciate answers or pointers to answers very much.
Cheers,
Michael
---------original post to g.g.help-----------------------
for a C course I gave the students the task to compute
FLT_EPSILON, DBL_EPSILON and LDBL_EPSILON.
We are using gcc 3.2 and gcc 3.4 on Linux machines.
The following
epsilon_float = 1.0F;
while (1.0 + eps_float != 1.0)
eps_float /= 2.0;
eps_float *= 2.0;
will give the students not FLT_EPSILON, but LDBL_EPSILON
in float precision, as the expressions in the condition for
while are evaluated in long double precision.
Now we apply the necessary type casts
epsilon_float = 1.0F;
while ((float)(1.0 + eps_float) != (float)1.0)
eps_float /= 2.0;
eps_float *= 2.0;
and everything works fine.
Right. Up to now, everything is fine and completely to my
understanding. But if I try the same with doubles, I get
LDBL_EPSILON even with the cast. (Example provided below)
Is this a problem in gcc or am I missing some finer points
of C? I tried RTFM and STFW but probably looked in the wrong
places.
It would be great if someone could tell me what is going
wrong or point me in the right direction.
Cheers,
Michael
gcc -Wall -std=c99 -pedantic castepsilon.c
--------------------------castepsilon.c-------------------
#include <stdio.h>
#include <float.h>
int main (void)
{
float eps_float = 1.0F;
double eps_double_test = 1.0, eps_double = 1.0;
long double eps_long_double = 1.0L;
// find FlT_EPSILON
while ((float)(1.0 + eps_float) != (float)1.0)
eps_float /= 2.0;
eps_float *= 2.0;
// find DBL_EPSILON
while ((double)(1.0 + eps_double_test) != (double)1.0)
eps_double_test /= 2.0;
eps_double_test *= 2.0;
// alternative way
for ( double test=1.0 + eps_double; test != (double)1.0;
test=1.0 + eps_double)
eps_double /= 2.0;
eps_double *= 2.0;
// find LDBL_EPSILON
while ((long double)(1.0 + eps_long_double) != (long double)1.0)
eps_long_double /= 2.0;
eps_long_double *= 2.0;
// Output
printf("Epsilon is --");
printf(" exact val\n");
printf(" - for float : %8.7g -- %8.7g\n",
eps_float, FLT_EPSILON);
printf(" - for double (1) : %17.16g -- %17.16g\n",
eps_double_test, DBL_EPSILON);
printf(" - for double (2) : %17.16g -- %17.16g\n",
eps_double, DBL_EPSILON);
printf(" - for long double: %20.19Lg -- %20.19Lg\n\n",
eps_long_double, LDBL_EPSILON);
return(0);
}
-------------------------------------------------------------------
mairml@cip20:~/C/test> ./a.out
Epsilon is -- exact value --
- for float : 1.192093e-07 -- 1.192093e-07
- for double (1) : 1.084202172485504e-19 -- 2.220446049250313e-16
- for double (2) : 2.220446049250313e-16 -- 2.220446049250313e-16
- for long double: 1.084202172485504434e-19 -- 1.084202172485504434e-19