¿El estándar C++ especifica algo en la representación de números de coma flotante?


Para los tipos T para los que std::is_floating_point<T>::value es true, ¿el estándar de C++ especifica algo sobre la forma en que T debe implementarse?

Por ejemplo, ¿T tiene que seguir una representación de signo/mantissa/exponente? ¿O puede ser completamente arbitrario?

Author: Peter Mortensen, 2015-12-15

4 answers

De N3337:

[basic.fundamental/8]: Hay tres tipos de punto flotante: flotador, doble y doble largo. El tipo double proporciona al menos tanta precisión como el flotador, y el tipo long double proporciona al menos tanta precisión como el doble. El conjunto de valores de tipo float es un subconjunto del conjunto de valores de tipo double; el conjunto de valores del tipo double es un subconjunto del conjunto de valores de tipo long double. La representación de valor de tipos de punto flotante es definición de implementación . Los tipos integral y flotante se denominan colectivamente aritmética tipo. Las especializaciones de la plantilla estándar std:: numeric_limits (18.3) especificarán el máximo y valores mínimos de cada tipo aritmético para una implementación.

Si desea comprobar si su aplicación utiliza IEEE-754, puede utilizar std::numeric_limits::is_iec559:

static_assert(std::numeric_limits<double>::is_iec559,
              "This code requires IEEE-754 doubles");

Hay un número de otro ayudante rasgos en esta área, tales como has_infinity, quiet_NaN y más.

 37
Author: TartanLlama,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-15 17:01:50

El estándar C tiene un "anexo" (en C11 es el Anexo F) que establece lo que significa para una implementación de C ser compatible con IEC 60559, el estándar sucesor de IEEE 754. Una implementación que se ajuste al anexo F debe tener números de punto flotante IEEE-representation. Sin embargo, la implementación de este anexo es opcional; la norma básica evita específicamente decir nada sobre la representación de números de coma flotante.

No sé si existe un anexo equivalente para C++. No aparece en N3337, pero eso podría significar que se distribuye por separado. La existencia de std::numeric_limits<floating-type>::is_iec559indica que el comité de C++ al menos pensó sobre esto, pero quizás no con tanto detalle como lo hizo el comité de C. (Es y siempre ha sido una maldita vergüenza que el estándar C++ no se exprese como un conjunto de ediciones al estándar C.)

 10
Author: zwol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-16 17:41:54

No se requiere ninguna aplicación particular. El estándar C++ no habla mucho de ello. El estándar C entra en un poco de detalle sobre el modelo conceptual asumido para los números de coma flotante, con un signo, exponente, significand en alguna base b, y así sucesivamente. Sin embargo, afirma específicamente que esto es puramente descriptivo, no un requisito de aplicación (C11, nota 21):

El modelo de coma flotante tiene por objeto aclarar la descripción de cada característica de coma flotante y no requiere que la aritmética de coma flotante de la implementación sea idéntica.

Dicho esto, aunque los detalles pueden variar, al menos de improviso me parece que producir (por ejemplo) una implementación conforme de double que no encajaba bastante estrechamente con el modelo habitual (es decir, un significativo y exponente) sería difícil (o al menos difícil de hacer con el rendimiento competitivo, de todos modos). No sería particularmente sin embargo, es difícil que varíe de otras maneras, como reorganizar el orden o usar una base diferente.

La definición de std::numeric_limits<T>::digits (y std::numeric_limits<T>::digits10) implica bastante directamente que lo que está listado como un tipo de coma flotante debe retener (al menos aproximadamente) la misma precisión para todos los números en un rango bastante amplio de magnitudes. Con mucho, la forma más obvia de lograr eso es tener algún número de bits / dígitos dedicados a un significand, y algún otro conjunto (separado) de bits dedicado a un exponente.

 7
Author: Jerry Coffin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-15 19:11:40

La idea de std::is_floating_point es hacer que el código de usuario de origen diferente funcione mejor en conjunto. Técnicamente se puede especificar un int como std::is_floating_point sin causar un comportamiento indefinido. Pero digamos que tiene alguna biblioteca templada que tiene que dividir repetidamente por T n. Para acelerar las cosas, la biblioteca crea un T ni = 1 / n y reemplaza la división por n por la multiplicación por ni. Esto funciona muy bien para los números de coma flotante, pero falla para los enteros. Por lo tanto, la biblioteca solo realiza correctamente la optimización si std::is_floating_point<T>::value == true. Si usted miente el código probablemente todavía funciona desde el punto de vista del estándar, pero es incorrecto desde un punto de vista lógico. Así que si escribes una clase que se comporta como un float más grande, márcalo como std::is_floating_point, de lo contrario no lo hagas. Esto debería darte tanto el código óptimo como el correcto.

 3
Author: nwp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-15 17:14:28