sirve que para number float ejemplos definicion and c floating-point

que - ¿Por qué MSVS no optimiza lejos+0? En cambio, ¿lo convierte en un flotador desnormalizado?



float c++ para que sirve (2)

Esta question demuestra un fenómeno muy interesante: los flotadores denormalized ralentizan el código más que un orden de magnitud.

El comportamiento está bien explicado en la respuesta aceptada . Sin embargo, hay un comentario, con actualmente 48 votaciones ascendentes, que no puedo encontrar una respuesta satisfactoria a:

¿Por qué el compilador no deja caer el +/- 0 en este caso?!? - Michael Dorgan

Nota al margen: tengo la impresión de que 0f es / debe ser exactamente representable (además, su representación binaria debe ser todos ceros), pero no puede encontrar dicha afirmación en el estándar c11. Una cita que demuestre esto, o un argumento que refute esta afirmación, sería muy bienvenido. De todos modos, la pregunta de Michael es la pregunta principal aquí.

§5.2.4.2.2

Una implementación puede dar cero y los valores que no son números de punto flotante (como infinitos y NaN) un signo o pueden dejarlos sin signo.


El compilador no puede eliminar la adición de un cero positivo de punto flotante porque no es una operación de identidad. Según las reglas IEEE 754, el resultado de agregar +0. a -0. no es -0 .; es +0.

El compilador puede eliminar la resta de +0. o la adición de -0. porque esas son operaciones de identidad.

Por ejemplo, cuando compilo esto:

double foo(double x) { return x + 0.; }

con Apple GNU C 4.2.1 usando -O3 en una Intel Mac, el código ensamblador resultante contiene addsd LC0(%rip), %xmm0 . Cuando compilo esto:

double foo(double x) { return x - 0.; }

no hay instrucción adicional; el conjunto simplemente devuelve su entrada.

Por lo tanto, es probable que el código en la pregunta original contenga una instrucción adicional para esta declaración:

y[i] = y[i] + 0;

pero no contenía instrucciones para esta declaración:

y[i] = y[i] - 0;

Sin embargo, la primera afirmación involucraba aritmética con valores subnormales en y[i] , por lo que fue suficiente para desacelerar el programa.


No es la constante cero 0.0f que se desnormaliza, sino los valores que se acercan a cero en cada iteración del ciclo. A medida que se acercan cada vez más a cero, necesitan más precisión para representar, de ahí la desnormalización. En la question , estos son los valores y[i] .

La diferencia crucial entre las versiones lenta y rápida del código es la afirmación y[i] = y[i] + 0.1f; . Tan pronto como se ejecuta esta línea, se pierde la precisión adicional en el flotador y ya no se necesita la desnormalización necesaria para representar esa precisión. Luego, las operaciones de coma flotante en y[i] permanecen rápidas porque no están desnormalizadas.

¿Por qué se pierde la precisión extra cuando se agrega 0.1f ? Debido a que los números de punto flotante solo tienen tantos dígitos significativos. Supongamos que tiene suficiente almacenamiento para tres dígitos significativos, luego 0.00001 = 1e-5 y 0.00001 + 0.1 = 0.1 , al menos para este formato flotante de ejemplo, porque no tiene espacio para almacenar el bit menos significativo en 0.10001 .