Por que a expressão (int) + 1e10 não produz -2147483648 como CSAPP descreve? [duplicado]
Estou lendo CS: APP (um x86-64 assembly / livro de baixo nível) e menciona:
De
float
oudouble
paraint
, o valor será arredondado para zero. Por exemplo,1.999
será convertido para1
, enquanto−1.999
será convertido para−1.
Além disso, o valor pode estourar. Os padrões C não especificam um resultado fixo para este caso. Os microprocessadores compatíveis com Intel designam o padrão de bits [10 ... 00] (TMinw
para o tamanho da palavraw
) como um valor inteiro indefinido. Qualquer conversão de ponto flutuante em inteiro que não pode atribuir uma aproximação de inteiro razoável produz esse valor. Assim, a expressão(int) +1e10
cede-2147483648
, gerando um valor negativo a partir de um positivo.
O que são microprocessadores compatíveis com Intel mencionados aqui? x86
arquitetura incluindo a série AMD?
De qualquer forma, tenho um Intel i5 com Win10 64 bits e tentei no Visual Studio:
#include <iostream>
using namespace std;
int main() {
int b = (int)+1e10;
cout << b << endl;
}
e obtém 1410065408
como saída.
Também tentei int32_t
e consegui 1410065408
também.
Então por que não tenho o resultado -2147483648
que [10 ... 00]
o livro descreve?
Respostas
Mesmo se o processador usado tiver "Qualquer conversão de ponto flutuante para inteiro que não pode atribuir uma aproximação de inteiro razoável produz esse valor.", O compilador não precisa seguir isso, pois pode usar outro código para atingir o objetivo.
Em particular, os valores que podem ser determinados no momento do compilador, como some_32_bit_int = (int)+1e10;
podem obter um valor como some_32_bit_int = 10000000000 & 0xFFFFFFFF;
ou 1410065408
que é completamente independente de um processador.
Se o valor da parte integral não pode ser representado pelo tipo inteiro, o comportamento é indefinido.
C17dr § 6.3.1.4 1
O livro descreve o processador, não o compilador.