2

如果 2^31-1 的二进制表示是 01111111 11111111 11111111 11111111,那么当类型转换为 short 时该二进制数会发生什么?这是假设一个 int 是 4 个字节,而一个 short 是 2 个字节。

我写了一个测试程序,当类型转换为short时输出为-1。它是否正确?这是否意味着 typecast to short 只是砍掉了 16 个最高有效位,留下 11111111 11111111 (有符号 2 的补码)?

代码

#include <stdio.h>
#include <stdlib.h>

void main()
{
        int x = sizeof(int);
        int y = sizeof(short);
        printf("%d, %d",x,y);

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

        printf("\nad: %d",(int)a);
        printf("\nax: %x",(int)a);
        printf("\nau: %u",(int)a);

        printf("\nbd: %d",(int)b);
        printf("\nbx: %x",(int)b);
        printf("\nbu: %u",(int)b);
        printf("\n");
}

输出

4, 2
ad: 2147483647
ax: 7fffffff
au: 2147483647
bd: -1
bx: ffffffff
bu: 4294967295
4

2 回答 2

5

当您将 an 分配int给 ashort时,如果该值不能在short( [-2^15, 2^15 - 1], 2 的补码) 的范围内表示,则结果是实现定义的。

6.3.1.3 有符号和无符号整数

当整数类型的值转换为_Bool以外的其他整数类型时,如果该值可以用新类型表示,则保持不变。否则,如果新类型是无符号的……否则,新类型是有符号的,值不能在其中表示;结果是实现定义的,或者引发了实现定义的信号。

至于“实现定义”,它意味着行为取决于编译器、体系结构等。具体而言,您可能已经看到,一种可能的结果是简单地丢弃高位。这导致11111111 11111111在这种情况下。

另一个可能的结果是它被“四舍五入”到该范围内的最大值。就是01111111 11111111在这种情况下。但我无法记住哪个实现是这样的。

但无论哪种方式,都不要依赖它。

于 2013-09-07T08:37:30.830 回答
5

C 或任何其他语言中的任何整数都以某些字节的形式存储(C 中的 4 个字节,如果您使用 32 位 C 编译器,通常大小int取决于编译器),当您将其类型转换为short并从内存中读取或分配给任何变量,只有较低的 2 个字节被读取或分配,因为short指示编译器将值读取为short int.

在您的情况下,整数是01111111 11111111 11111111 11111111二进制的,因此,当对其进行类型转换时,short它被读取为11111111 11111111(低 2 个字节),它是 16 位的二进制表示-1(当然,如果它signed short是默认的)。

我的意思是,假设你有一个int a = 0x7fffffff存储在地址 say 1234,那么内存表示a将是:

 Memory Address:  1237     1236     1235     1234  
 Value:         01111111 11111111 11111111 11111111

当您将其读取为 时short,仅读取低 2 个字节(地址 1235 和 1234)。
现在将它们读为short(或有符号短)意味着您希望编译器将数字的 MSB视为符号位。因为Sign bit = 1意味着它是一个负数,并且如果您知道 2 的补数格式(C 编译器使用它来表示整数),那么11111111 11111111二进制数等于-1十进制数。

此外,当您使用%u或打印该short int值时,它被视为unsigned,MSB(这次)对幅度有贡献,而不是符号位。

我还想补充一件事:从shortto类型转换int
每当您像shortint以下那样键入时:

short b = (short)a;
printf("\nbu: %u",(int)b);

符号位被填充到所有额外的高位中,因此变为11111111 1111111111111111 11111111 11111111 11111111符号十进制4294967295

如果您尝试进行类型转换01111111 11111111而不是11111111 11111111then 它将被提升为00000000 00000000 01111111 11111111since sign bit is 0

希望你明白我的解释。

于 2013-09-07T08:38:58.103 回答