类型转换——在C语言中,当一个较大的数据类型(如int)被转换为较小的数据类型(如short)时会发生什么



当我在下面的代码中遇到这个问题时,我正在玩类型转换。

int i = 123456;
short s = i;
printf("%i",s);

这里的int值被C编译器隐式地转换为short值。打印此值,将在控制台输出上显示-7616。我知道short的范围比int的范围小,但我需要知道C语言是如何从123456得到这个值-7616的,而不是截断它,我想这是直观的选择。

值正在被截断,但不是按您期望的方式。

十进制值123456的十六进制值0x1E240。当将此值分配给short时,在您的情况下看起来是16位,它只需要较低的16位,即0xE240

如果sunsigned short,它的值将为57920。但是因为它是带符号的,所以这个值被解释为带符号的。由于您的机器似乎在使用二进制补码表示负数,因此0xE240的十进制等效值为-7616(= 57920 - 65536)。

注意,这个行为是实现定义的,所以你不能指望它发生在不同的机器或不同的编译器上。

值在转换过程中被截断,保留较低的位,但丢失较高的位。无论您使用的是大端序机器还是小端序机器,这都是一致的。

在您的具体示例中,123456以二进制形式写成11110001001000000。请记住,整型数使用4个字节,因此我在中省略了一堆前导零。short限制为2字节,立即严格截断为1110001001000000。注意,前面有一个1,在2的补码中,它立即表示一个负数。通过2的补码过程可以看到如何得到所得到的结果。

在C语言中,当你将int型转换为short型时,你已经在自找麻烦了。在处理.wav文件的情况下,在使用一系列if语句控制截断之前,通常使用int数据类型来操作属性。

//you will need to #include <limits.h>
int i = 123456;
short s;
if(i > SHRT_MIN && i < SHRT_MAX) //if your int is within the range of shorts
{
    s = i;
}

//if your int is too large or too negative, you can control the truncation
if(i < SHRT_MIN) //if int is too negative
{
    i=SHRT_MIN;
}
else //if int is too positive
{
    i=SHRT_MAX;
}

假设一个4位整数被转换成2位整数。第一个位决定数字是正(0)还是负(1)0111 (dec: 7)转换为11 (dec: -1)。它将切割更高的部分。因为第一个位1代表-,所以它将是负的。

数据类型short(2字节大小)的取值范围为[-32768]到[32767]。

int main()
{
    int i = 32767;
    short c = i;
    printf("%dn",c);
    c = i+1;
    printf("%dn",c);
    c = i+2;
    printf("%dn",c);
}
//Output:
32767
-32768  << rolling
-32767  << rolling

如果short被分配的值大于允许的最大值(即[32767]),则值继续从最小值(-32768)滚动到最大值

int main()
{
    int i = -32768;
    short c = i;
    printf("%dn",c);
    c = i-1;
    printf("%dn",c);
    c = i-2;
    printf("%dn",c);
}
//Output:
-32768
32767  << rolling
32766  << rolling

如果short分配的值小于允许的最小值(即[-32768]),则值从最大值(32767)滚动到最小值

最新更新