Dlaczego wyrażenie (int) + 1e10 nie daje -2147483648, jak opisuje CSAPP? [duplikować]

Dec 12 2020

Czytam CS: APP (zbiór x86-64 / podręcznik niskiego poziomu) i wspomina o:

Od floatlub doubledo intwartość zostanie zaokrąglona w kierunku zera. Na przykład 1.999zostanie przekonwertowany na 1, podczas gdy −1.999zostanie przekonwertowany na −1.Ponadto wartość może się przepełnić. Normy C nie określają stałego wyniku dla tego przypadku. Mikroprocesory kompatybilne z Intel wyznaczają wzór bitowy [10… 00] ( TMinwdla rozmiaru słowa w) jako nieokreśloną wartość całkowitą. Każda konwersja ze zmiennoprzecinkowej na liczbę całkowitą, która nie może przypisać rozsądnego przybliżenia liczby całkowitej, daje tę wartość. W ten sposób wyrażenie (int) +1e10daje -2147483648, generując ujemną wartość z dodatniej.

O jakich mikroprocesorach jest mowa w tym miejscu? x86architektura obejmująca serię AMD?

W każdym razie mam Intel i5 z 64-bitową maszyną Win10 i próbowałem pod Visual Studio:

    #include <iostream>
    using namespace std;
    
    int main() {
        int b = (int)+1e10;
        cout << b << endl;
    }

i otrzymuje 1410065408jako wyjście.

Również próbowałem int32_ti 1410065408też dostaje .

Więc dlaczego nie mogę mieć wynik -2147483648, który jest [10 ... 00]jak książka opisuje?

Odpowiedzi

2 chux-ReinstateMonica Dec 12 2020 at 09:49

Nawet jeśli używany procesor ma „Każda konwersja z wartości zmiennoprzecinkowej na liczbę całkowitą, która nie może przypisać rozsądnego przybliżenia liczby całkowitej, daje tę wartość”, kompilator nie musi tego przestrzegać, ponieważ może użyć innego kodu, aby osiągnąć cel.

W szczególności wartości, które można określić w czasie kompilacji, takie jak, some_32_bit_int = (int)+1e10;mogą otrzymać wartość podobną some_32_bit_int = 10000000000 & 0xFFFFFFFF;lub 1410065408całkowicie niezależną od procesora.

Jeśli wartość części całkowitej nie może być reprezentowana przez typ całkowity, zachowanie jest niezdefiniowane. C17dr § 6.3.1.4 1

Książka opisuje procesor, a nie kompilator.