当我在下面的代码中遇到这个问题时,我正在玩类型转换。
int i = 123456;
short s = i;
printf("%i",s);
这里的int值被C编译器隐式地转换为short值。打印此值,将在控制台输出上显示-7616。我知道short的范围比int的范围小,但我需要知道C语言是如何从123456得到这个值-7616的,而不是截断它,我想这是直观的选择。
值正在被截断,但不是按您期望的方式。
十进制值123456的十六进制值0x1E240
。当将此值分配给short
时,在您的情况下看起来是16位,它只需要较低的16位,即0xE240
。
如果s
是unsigned 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)滚动到最小值