将int转换为C中的short

时间:2013-08-16 14:54:15

标签: c int short

我有:

int a = 2147483647;
short b = (short)a;

我得到b = -1,而我希望int32转换为int16short)。我希望看到一些价值, -1

请有人帮助我。

5 个答案:

答案 0 :(得分:23)

值2147483647或2 31 -1溢出16位整数。其二进制表示在MSB中为零,其余位为31个。

在您的实现中,最后的16位在转换为short时被采用。发生这种情况时,所有这些都设置为1,从而导致-1代表32-bit int: 01111111111111111111111111111111 16-bit short: ----------------1111111111111111

{{1}}

但是,2-compliment表示和这种行为通常都不是C ++标准的一部分,所以这种行为是实现定义的。

答案 1 :(得分:11)

将值转换为 signed 类型,当源值不适合目标类型时,会产生实现定义的结果。这意味着任何符合标准的编译器文档都必须记录结果。

(这与算术运算符溢出时的行为不同。例如:

int overflow = INT_MAX + 1;

实际上有未定义的行为。但在任何一种情况下,都应该小心编写代码,这样就不会触发这种问题。)

对于许多实现,对于转换和算术,目标是N位类型的溢出只需要正确结果的N个低位。

在您的情况下,显然int是32位而short是16位(这些大小可能因不同的实现而有所不同)。 21474836470x7fffffff,低16位为0xffff,这是(在您的实施时)-1类型short的表示形式。

对于转换为无符号类型,结果严格按标准定义;它需要结果的低位N位。对于溢出的浮点转换(例如,将非常大的double值转换为float),行为未定义。

到目前为止,C和C ++的情况完全相同。但只是为了增加混乱,从1999年标准开始,允许溢出的带符号转换引发实现定义的信号。 C ++没有这个。我不知道任何编译器实际上是这样做的。

  

我希望看到一些价值, -1

-1 “有些价值”。你有什么特定的价值吗?

顺便提及:

short b = (short)a;

演员阵容是不必要的。赋值,初始化,参数传递和return语句可以在没有强制转换的情况下在任何数字类型之间分配值。该值隐式转换:

short b = a;

答案 2 :(得分:7)

这是implementation defined行为,例如gcc Integers Implementation document说:

  

为了转换为宽度N的类型,值以模2 ^ N减小到类型的范围;没有信号被提出。

这可能因编译器而异,我无法挖掘clangvisual studio的类似文档。

从草案C ++标准开始,4.7 Integral conversions3

  

如果目标类型已签名,则如果可以在目标类型(和位字段宽度)中表示,则该值不会更改;否则,该值是实现定义的

如果这是unsigned,那么根据段落2,您将拥有完美定义的行为:

  

如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模2n,其中n是用于表示无符号类型的位数)。 [注意:在二进制补码表示中,此转换是概念性的,并且位模式没有变化(如果没有截断)。 - 后注]

C99草稿标准部分6.3.1.3 Signed and unsigned integers中的语言类似。

答案 3 :(得分:6)

你的int A大于short的大小。将A转换为short时,最左边的位数为1,这表示它是负数。因为你得到-1,我想你在所有16位中得到1,这将给你-2 ^ 15 + 2 ^ 14 + 2 ^ 13 ... + 2 ^ 0,这将给你-1。简而言之(没有双关语),如果它太大,则无法将整数转换为short。

答案 4 :(得分:3)

你可以这样做:

uint32_t sum=0xFFFF1234;
uint16_t *p= (uint16_t *) ∑
uint16_t checksum=p[0]; 

check-sum是0x1234

这是另一种方式:

union ToShort
{
        uint32_t sum;
        uint16_t checksum[2];
} toShort;
toShort.sum=0xFFFF1234;
cout << hex << toShort.checksum[0];

输出为1234