I have:
int a = 2147483647;
short b = (short)a;
and I get b = -1
whereas I expect int32
to be converted to int16
(short
). I expect to see some value and not -1
.
Please someone help me with this.
I have:
int a = 2147483647;
short b = (short)a;
and I get b = -1
whereas I expect int32
to be converted to int16
(short
). I expect to see some value and not -1
.
Please someone help me with this.
You can do this:
check-sum is
0x1234
.Here is another way:
output is
1234
.Converting a value to a signed type, when the source value doesn't fit in the target type, yield an implementation-defined result. That means that any conforming compiler's documentation must document what that result is.
(This is unlike the behavior on overflow of an arithmetic operator. For example:
actually has undefined behavior. But in either case, you should be careful to write your code so it doesn't trigger this kind of problem.)
For many implementations, for both conversion and arithmetic, an overflow where the target is an N-bit type simply takes the N low-order bits of the correct result.
In your case, apparently
int
is 32 bits andshort
is 16 bits (those sizes can vary on different implementations).2147483647
is0x7fffffff
, the low-order 16 bits are0xffff
, which is (again, on your implementation) the representation of-1
in typeshort
.For conversion to unsigned types, the result is strictly defined by the standard; it takes the low-order N bits of the result. And for overflowing floating-point conversion (say, converting a very large
double
value tofloat
), the behavior is undefined.So far, this is all the same for C and C++. But just to add to the confusion, starting with the 1999 standard an overflowing signed conversion is permitted to raise an implementation-defined signal. C++ doesn't have this. I don't know of any compiler that actually does this.
-1
is "some value". Was there some specific value you expected?Incidentally:
The cast is unnecessary. Assignment, initialization, parameter passing, and
return
statements can assign values between any numeric types without a cast. The value is converted implicitly:Your int A is larger than the size of short. When you convert A to short, you get a 1 in the left most bit, which is going to indicate that it is a negative number. Since you're getting -1, I suppose you're getting 1s in all 16 bits, which is going to give you -2^15 + 2^14 + 2^13... + 2^0, which will give you -1. In short (no pun intended), you can't convert the integer to a short if it is too large.
The value 2147483647, or 231-1 overflows a 16-bit integer. Its binary representation is zero in the MSB followed by 31 ones in the remaining bits.
It looks like in your implementation the last 16 bits are taken in the conversion to
short
. When this happens, all of them are set to1
, resulting in a 2's complement representation of-1
:However, neither the 2-compliment representation nor this behavior in general is part of the C++ standard, so this behavior is implementation-defined.
This is
implementation defined
behavior, for examplegcc
Integers Implementation document
says:This can differ from compiler to compiler, I am not able to dig up similar documents for
clang
norvisual studio
.From the draft C++ standard, section
4.7 Integral conversions
paragraph3
:If this was
unsigned
then you would have perfectly well defined behavior, as per paragraph2
:The language is similar in the
C99
draft standard section6.3.1.3 Signed and unsigned integers
.