Visual C++ 6 SP6에서의 명시적 형변환을 믿지마세요(?)

#include <iostream>

using namespace::std;

int main(void)
{
    float f = 1234567890;
    int i = f;
    int i2 = float(1234567890);
   
    cout << i << endl;
    cout << i2 << endl;

    return 0;
}

위 코드에서 i와 i2가 다를까요? 네. 다릅니다. Visual C++ 6를 쓰신다면요..;;

발견하게 된 계기는 다음과 같습니다.

“The C++ Programming Language” 의 C.6.2.6 부동소수점 실수-정수 변환 절에는 다음과 같은 절이 나옵니다.

반대로, 정수를 부동소수점 실수 타입으로 바꾸는 것은 하드웨어가 허용하는 한 수학적으로 정확히 보장된다. 단, 정밀도가 손실되는 경우는 주어진 정수를 해당 부동소수점 실수 타입으로 정확히 표현할 수 없을 때이다.
    int i = float(1234567890);
int와 float를 32비트로 처리하는 컴퓨터에서는 i에 1234567936이 들어간다.

제 컴퓨터는 int와 float를 32비트로 처리합니다. 따라서 같은 결과를 예상하고 다음과 같은 코드를 작성합니다.

#include <iostream>

using namespace::std;

int main(void)
{
    int i = float(1234567890);
   
    cout << i << endl;

    return 0;
}

결과는?

1234567890

허걱! 뭐야..;; float 형을 32비트로 처리 안하나? sizeof 로 확인해보니 4 랍니다. 그럽 32비트 맞겠죠? float형 정밀도가 저 범위를 모두 처리할 수 있나? 1비트 사인비트에 8비트 지수, 23비트로 mantisa를 처리하니.. 안될텐데;; 1234567890 은 2진수로 “1001001100101100000001011010010” 니까 31비트인데..;; 뭐지..;; 책 내용은 맞는 것 같은데… 까지 생각하고 혹시 컴파일러 문제인가? 하고 2005를 띄웁니다.

같은 코드에 결과는 책과 같은 결과가 나옵니다.

으음.. 그럼 얘는 뭘까 형변환을 명시적으로 안하는 건가 라고 생각하고 그냥 float 형에 넣어봅니다.

#include <iostream>

using namespace::std;

int main(void)
{
    float f = 1234567890;
    int i = f;
   
    cout << i << endl;
 
    return 0;
}

이제서야 책과 같은 결과가 나옵니다. 헐……….. 뭘까요… 얘…..