Aritmética de punto flotante y épsilon de máquina.

Estoy tratando de calcular una aproximación del valor épsilon para elfloat tipo (y sé que ya está en la biblioteca estándar).

Los valores de épsilon en esta máquina son (impresos con cierta aproximación):

 FLT_EPSILON = 1.192093e-07
 DBL_EPSILON = 2.220446e-16
LDBL_EPSILON = 1.084202e-19

FLT_EVAL_METHOD es2 así que todo se hace enlong double precisión, yfloat, double ylong double Son 32, 64 y 96 bits.

Intenté obtener una aproximación del valor comenzando desde 1 y dividiéndolo por 2 hasta que sea demasiado pequeño, haciendo todas las operaciones con elfloat tipo:

# include <stdio.h>

int main(void)
{
    float floatEps = 1;

    while (1 + floatEps / 2 != 1)
        floatEps /= 2;

    printf("float eps = %e\n", floatEps);
}

La salida no es lo que estaba buscando:

float epsilon = 1.084202e-19

Las operaciones intermedias se realizan con la mayor precisión (debido al valor deFLT_EVAL_METHOD), por lo que este resultado parece legítimo.

Sin embargo, esto:

// 2.0 is a double literal
while ((float) (1 + floatEps / 2.0) != 1)
    floatEps /= 2;

da esta salida, que es la correcta:

float epsilon = 1.192093e-07

pero este:

// no double literals
while ((float) (1 + floatEps / 2) != 1)
    floatEps /= 2;

Conduce nuevamente a un resultado equivocado, como el primero:

float epsilon = 1.084202e-19

Estas dos últimas versiones deberían ser equivalentes en esta plataforma, ¿se trata de un error del compilador? Si no, ¿qué está pasando?

El código se compila con:

gcc -O0 -std=c99 -pedantic file.c

La versión de gcc es bastante antigua, pero estoy en la universidad y no puedo actualizarla:

$ gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.5-8'
--with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4
--enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls
--enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc
--enable-targets=all --with-arch-32=i586 --with-tune=generic
--enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu
--target=i486-linux-gnu
Thread model: posix
gcc version 4.4.5 (Debian 4.4.5-8)

La versión actual de gcc, 4.7, se comporta correctamente en la computadora de mi hogar. También hay comentarios que dicen que las diferentes versiones dan diferentes resultados.

Después de algunas respuestas y comentarios, eso aclaró qué se está comportando como se esperaba y qué no, cambié un poco la pregunta para aclararla.

Respuestas a la pregunta(2)

Su respuesta a la pregunta