2

I am reading CS:APP (an x86-64 assembly / low-level textbook) and it mentions:

From float or double to int, the value will be rounded toward zero. For example, 1.999 will be converted to 1, while −1.999 will be converted to −1. Furthermore, the value may overflow. The C standards do not specify a fixed result for this case. Intel-compatible microprocessors designate the bit pattern [10 ... 00] (TMinw for word size w) as an integer indefinite value. Any conversion from floating point to integer that cannot assign a reasonable integer approximation yields this value. Thus, the expression (int) +1e10 yields -2147483648, generating a negative value from a positive one.

What is Intel-compatible microprocessors mentioned here? x86 architecture including AMD series?

Anyway, I have an Intel i5 with Win10 64bit machine and I tried under Visual Studio:

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

and gets 1410065408 as output.

Also I tried int32_t and gets 1410065408 too.

So why don't I have the result -2147483648 which is [10 ... 00] as the book describes?

Rick
  • 4,467
  • 1
  • 22
  • 49
  • 2
    The book is misleading at best. There exists an instruction in x86-64 that will convert float to int with that overflow behavior. But there's no guarentee that the C compiler will use it in a way to get that value. – Chris Dodd Dec 12 '20 at 02:05
  • 2
    Typo note: the number you want is -2147483648. You seem to have dropped a couple of digits. – Nate Eldredge Dec 12 '20 at 02:20
  • Look at the asm your compiler produces to find out what it did. It's unlikely to do a runtime conversion even in a debug build, when the value is there as a numeric literal in the same expression as the cast. Related: [Bizarre floating-point behavior with vs. without extra variables, why?](https://stackoverflow.com/q/21478945) Actually looks like a duplicate. – Peter Cordes Dec 12 '20 at 03:11
  • @PeterCordes Is my quesiton really a duplicated of those 3? I took a glance and couldn't tell. But so far I am satisfied with the first comment and the answer below. Telling me that's an UB is also enough for me :). I don't know much about assembly :P . – Rick Dec 12 '20 at 06:34
  • Yes, the fact that it's UB that's visible at compile time is the key. The 3 duplicates have different examples showing weird stuff happening, as well as some details about what does happen in asm like CS:APP is talking about. If it wasn't visible at compile time, the compiler would use `cvttsd2si eax, xmm0` (or whatever registers) which would give you what Intel calls the integer-indefinite bit-pattern, `0x80000000`. – Peter Cordes Dec 12 '20 at 12:46

1 Answers1

2

Even if the processor used has "Any conversion from floating point to integer that cannot assign a reasonable integer approximation yields this value.", the compiler is not required to follow that as it can use other code to achieve the goal.

In particular, values that can be determine at compiler time like some_32_bit_int = (int)+1e10; may get an value like some_32_bit_int = 10000000000 & 0xFFFFFFFF; or 1410065408 that is completely independent of a processor.

If the value of the integral part cannot be represented by the integer type, the behavior is undefined. C17dr § 6.3.1.4 1

The book describes the processor, not the compiler.

chux - Reinstate Monica
  • 113,725
  • 11
  • 107
  • 213
  • 2
    It's not just implementation-defined; FP -> integer conversion with a value not representable in the destination type is fully undefined behaviour. If the program does do anything at all, there's zero requirement that it print the same value in similar situations. (And of course it would be allowed to subtly or completely corrupt everything else in the program's execution, *before* and after hitting that UB, but in practice that's not a plausible outcome of out-of-range FP->int or unsigned conversion.) – Peter Cordes Dec 12 '20 at 03:19
  • @PeterCordes Yes it is UB. (Conflated with integer to FP which is IDB). Answer amended. – chux - Reinstate Monica Dec 12 '20 at 04:22