Pregunta promoción de punto flotante: stroustrup vs compiler - ¿quién tiene razón?


En la sección 10.5.1 del nuevo libro de Stroustrup "El lenguaje de programación C ++ - Cuarta edición", dice, antes de realizar una operación aritmética, la promoción integral se usa para crear enteros de tipos enteros más cortos, y de manera similar, la promoción de punto flotante es utilizado para crear dobles de flotadores.

Confirmé el primer reclamo con el siguiente código:

#include <iostream>
#include <typeinfo>

int main()
{
    short a;
    short b;
    std::cout << typeid(a + b).name() << std::endl;
}

Esto produce "int" con vc ++ e "i" con gcc.

Pero probándolo con flotadores en lugar de cortos, la salida sigue siendo "flotante" o "f":

#include <iostream>
#include <typeinfo>

int main()
{
    float a;
    float b;
    std::cout << typeid(a + b).name() << std::endl;
}

Según Stroustrup, no hay excepciones a la regla de promoción de coma flotante, por lo que esperaba "doble" o "d" como salida.

¿La sección mencionada sobre promociones está equivocada o de alguna manera no está clara? ¿Y hay alguna diferencia en C ++ 98 y C ++ 11 con respecto a las promociones de tipo?


32
2018-06-20 13:53


origen


Respuestas:


No sé exactamente qué dice el libro de Stroustrup, pero de acuerdo con el estándar, floats no se convertirán a doubles en este caso. Antes de aplicar la mayoría de los operadores binarios aritméticos, conversiones aritméticas usuales descrito en 5p9 se aplican:

  • Si cualquiera de los dos operandos tiene el tipo de enumeración con ámbito (7.2), no se realizan conversiones; si el otro operando no tiene el mismo tipo, la expresión está mal formada.
  • Si cualquiera de los dos operandos es del tipo double long, el otro se convertirá a double double.
  • De lo contrario, si cualquiera de los dos operandos es doble, el otro se convertirá en doble.
  • De lo contrario, si alguno de los operandos es flotante, el otro se convertirá en flotante.
  • De lo contrario, las promociones integrales (4.5) se realizarán en ambos operandos. [...]

Las promociones integrales son lo que causa dos shorts para convertir a ints. Pero dos floats no se convertirán a doubles de acuerdo con estas reglas. Si agrega un float a un double, el float se convertirá en un double.

Lo anterior es de C ++ 11. C ++ 03 contiene las mismas reglas, a excepción de la que hace referencia a las enumeraciones de ámbito.


29
2018-06-20 14:02



Mientras tanto, Stroustrup parece reconocer que la oración de referencia no es correcta o al menos engañosa. Él ha eliminado la oración, sobre la promoción de coma flotante, de la sección 10.5.1.

Por favor mira errata de la 3ª impresión de la 4ª edición en la página web de Stroustrup:

pg 267: s / De manera similar, la promoción de punto flotante se usa para crear dobles de flotadores //

(Observación: la expresión s / regexp / replacement / es similar a sed semántica de herramientas de Unix. Busca el patrón regexp y lo reemplaza con reemplazo. Nada en nuestro caso.)


5
2017-09-20 18:57