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.