¿Por qué la expresión (int) + 1e10 no produce -2147483648 como describe CSAPP? [duplicar]
Estoy leyendo CS: APP (un ensamblaje x86-64 / libro de texto de bajo nivel) y menciona:
Desde
float
odouble
hastaint
, el valor se redondeará a cero. Por ejemplo,1.999
se convertirá a1
, mientras−1.999
que se convertirá en−1.
Además, el valor puede desbordarse. Los estándares C no especifican un resultado fijo para este caso. Los microprocesadores compatibles con Intel designan el patrón de bits [10 ... 00] (TMinw
para el tamaño de la palabraw
) como un valor entero indefinido. Cualquier conversión de punto flotante a entero que no pueda asignar una aproximación de entero razonable produce este valor. Así, la expresión(int) +1e10
cede-2147483648
, generando un valor negativo a partir de uno positivo.
¿Qué se mencionan aquí los microprocesadores compatibles con Intel ? x86
arquitectura que incluye la serie AMD?
De todos modos, tengo una máquina Intel i5 con Win10 de 64 bits y probé en Visual Studio:
#include <iostream>
using namespace std;
int main() {
int b = (int)+1e10;
cout << b << endl;
}
y obtiene 1410065408
como salida.
También lo intenté int32_t
y 1410065408
también lo conseguí .
Entonces, ¿por qué no obtengo el resultado -2147483648
que se [10 ... 00]
describe en el libro?
Respuestas
Incluso si el procesador utilizado tiene "Cualquier conversión de punto flotante a entero que no pueda asignar una aproximación de entero razonable produce este valor", el compilador no está obligado a seguir eso, ya que puede usar otro código para lograr el objetivo.
En particular, los valores que se pueden determinar en el momento del compilador como some_32_bit_int = (int)+1e10;
pueden obtener un valor como some_32_bit_int = 10000000000 & 0xFFFFFFFF;
o 1410065408
que es completamente independiente de un procesador.
Si el valor de la parte integral no puede ser representado por el tipo entero, el comportamiento es indefinido.
C17dr § 6.3.1.4 1
El libro describe el procesador, no el compilador.