c++ undefined-behavior

c++ - ¿La conversión de infinito a entero no está definida?



undefined-behavior (3)

¿La conversión de infinito (representada por flotación) en un entero es un comportamiento indefinido?

La norma dice:

4.10 conversiones flotantes-integrales

Un prvalue de un tipo de punto flotante se puede convertir en un prvalue de un tipo entero. La conversión trunca; es decir, se desecha la parte fraccionaria. El comportamiento no está definido si el valor truncado no se puede representar en el tipo de destino.

pero no puedo decir si "el valor truncado no se puede representar" cubre el infinito.

Estoy tratando de entender por qué std::numeric_limits<int>::infinity() y static_cast<int>(std::numeric_limits<float>::infinity() ) tienen resultados diferentes.

#include <iostream> #include <limits> int main () { std::cout << std::numeric_limits<int>::infinity () << std::endl; std::cout << static_cast<int> (std::numeric_limits<float>::infinity () ) << std::endl; return 0; }

Salida:

0 -2147483648

El resultado de std::numeric_limits<int>::infinity() está bien definido y es igual a 0 , pero no puedo encontrar ninguna información sobre el lanzamiento de infinito.


Estoy tratando de entender por qué std::numeric_limits<int>::infinity() y static_cast<int>(std::numeric_limits<float>::infinity() ) tienen resultados diferentes.

La norma dice: 18.3.2.4

estática constexpr T infinito () noexcept;

47 Representación del infinito positivo, si está disponible. [216]

48 Significativo para todas las especializaciones para las que has_infinity! = Falso. Requerido en las especializaciones para las cuales is_iec559! = False.

--- editar ---

Según 18.3.2.7/1 [numeric.special]

1 Todos los miembros serán provistos para todas las especializaciones. Sin embargo, solo se requiere que muchos valores sean significativos en ciertas condiciones (por ejemplo, epsilon () solo es significativo si is_integer es falso). Cualquier valor que no sea "significativo" se establecerá en 0 o falso.


La conversión de infinito a entero no está definida.

El comportamiento no está definido si el valor truncado no se puede representar en el tipo de destino.

Lo dice todo. Como el truncamiento elimina la precisión pero no la magnitud, un infinito truncado sigue siendo infinito y los enteros no pueden representar infinito.


Tu dijiste

No puedo decir si "el valor truncado no se puede representar" cubre el infinito

pero todo se reduce a

¿Cuál es el resultado de truncar el infinito?

El estándar C (incorporado en C ++ a través de 26.9) responde que claramente:

Dado que el truncamiento del infinito sigue siendo infinito, y el infinito no puede representarse en int (espero que no haya dudas sobre esta parte), el comportamiento no está definido.