tiro tipos tecnicas tecnica suspensión son pases las lanzamientos fundamentales estatico entrada cuales bandeja baloncesto c++ casting g++ int double

c++ - tipos - Extraño comportamiento cuando el lanzamiento estático de un gran doble a un número entero



tiro en suspensión (2)

Del estándar C (1999):
6.3.1.4 Flotante real y entero
1 Cuando un valor finito del tipo flotante real se convierte a un tipo entero distinto de _Bool, la parte fraccionaria se descarta (es decir, el valor se trunca hacia cero). Si el valor de la parte integral no puede representarse mediante el tipo entero, el comportamiento no está definido.

Del estándar C ++ (2003):
4.9 Conversiones flotantes-integrales [conv.fpint]
1 Un valor de un tipo de punto flotante se puede convertir a un valor r de un tipo entero. La conversión trunca; es decir, la parte fraccional se descarta. El comportamiento no está definido si el valor truncado no se puede representar en el tipo de destino. [Nota: si el tipo de destino es bool, vea 4.12. ]

Lo más probable es que su doble sea demasiado grande para convertirse correctamente en int.

Aquí está mi código simple:

int main() { double d1 = 10000000000.0; const double d2 = 10000000000.0; cout << static_cast<int>(d1) << endl; cout << static_cast<int>(d2) << endl; cout << static_cast<int>(10000000000.0) << endl; }

El resultado es:

-2147483648 2147483647 2147483647

Esto me sorprendió grealy. ¿Por qué un doble positivo a veces se convierte en un int negativo?

Estoy usando g++ : GCC versión 4.4.3 (Ubuntu 4.4.3-4ubuntu5).


Lanzar un double a un int cuando int no es lo suficientemente grande como para mantener el valor produce un comportamiento indefinido .

[n3290: 4.9/1]: un prvalue de un tipo de coma flotante se puede convertir a un prvalue de un tipo entero. La conversión trunca; es decir, la parte fraccional se descarta. El comportamiento no está definido si el valor truncado no se puede representar en el tipo de destino.

Este comportamiento se deriva de C:

[C99: 6.3.1.4/1]: cuando un valor finito del tipo flotante real se convierte a un tipo entero distinto de _Bool , la parte fraccionaria se descarta (es decir, el valor se trunca hacia cero). Si el valor de la parte integral no puede representarse mediante el tipo entero, el comportamiento no está definido.

Para ti, int claramente no es lo suficientemente grande.

  • Y, en el primer caso, esto da como resultado que se establezca el bit de signo.
  • En el segundo y tercer caso, nuevamente para usted, es probable que las optimizaciones resulten en un comportamiento diferente.

Pero no confíe en ninguna (o, de hecho, ninguna ) conducta en este código.