Please have a look at this code:
#include <stdio.h>
int main(void)
{
short s;
int i = 65696;
float f = 65696.0F;
printf("sizeof(short) = %lu\n", sizeof(short));
s = i;
printf("s = %hd\n", s);
s = f;
printf("s = %hd\n", s);
s = 65696;
printf("s = %hd\n", s);
s = 65696.0F;
printf("s = %hd\n", s);
return 0;
}
It gave output as :
sizeof(short) = 2
s = 160
s = 160
s = 160
s = 32767
In last line why it's 32767 and not 160 ? What's the difference between saying f = 65696.0F; s = f;
and s = 65696.0F;
?
Because if the integral part of the float value is not representable in the new type, the conversion is undefined behavior.
In your case, SHRT_MAX
is probably 32767 and so the integral part of 65696.0F
is then not representable in a short
object.
This is "undefined behaviour," which means that the compiler is free to do what it wants. But "undefined" does not mean "unexplainable."
What the compiler is doing in the case of s = f
is converting f
first to the int
value 65696, and then assigning 65696 to s, which overflows and leaves 160. The compiler does this because there is a CPU instruction to convert a floating point number into a 32-bit integer, but not directly into a 16-bit integer
What the compiler is doing with s = 65696.0F
is simpler: It knows that 65696.0 is out of range, so it assigns the highest value available to s
, which happens to be 2^15-1 = 32767.
You can verify this if you read the assembly code the compiler generates for s = f (for example using -S switch with gcc):
movss -4(%rbp), %xmm0 # Load float from memory into register xmm0
cvttss2si %xmm0, %eax # Convert float in xmm0 into signed 32 bit, store in eax
movw %ax, -10(%rbp) # Store lower 16 bits of eax into memory
movswl -10(%rbp), %eax # Load those 16 bits into eax, with sign extend
The last instruction clobbers the high 16 bits of %eax, setting it to all 0s in this case.
What it generates for s = 65696.0F is simpler:
movw $32767, -10(%rbp) # Store the lower 16 bits of 32767 into memory
movswl -10(%rbp), %eax # Load those 16 bits into eax, with sign extend
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With