C 中短变量的值

Value of a short variable in C

我有一个带有简短变量声明的简单程序:

    short int v=0XFFFD;  
    printf("v = %d\n",v);  
    printf("v = %o\n",v);  
    printf("v = %X\n",v);

结果是:

v = -3 ; v = 37777777775 ; v = FFFFFFFD

我不明白如何计算这些值。我知道一个短变量可以保存 -32768 和 32767 之间的值,值 0XFFFD 会导致溢出,但我不知道如何计算确切的值,在这种情况下是 -3。

此外,如果我的声明是 v=0XFFFD 为什么输出 v=%X 是 FFFFFFFD?

首先,short 可以短至 16 位(您的编译器可能就是这种情况)。这意味着 65533 无法正确表示,赋值溢出,它换行到 -3(因为 short int 是一个带符号的短整数)。但你已经知道了。

其次,当作为参数发送给 printf 时,short int 会自动转换为 int,但由于 v 包含 -3,这就是发送到 printf

第三,%o%X 转换需要一个 unsigned int,这与您提供的不完全相同。这意味着未定义的行为(理论上),但实际上它是可以预测的。这意味着 -3 的位模式被解释为一个无符号整数,而在 32 位机器上恰好是 0xFFFFFFFD.

如果 short 在这台机器上是 2 个字节,那么 0x8000 是这种类型持有的最大负值的二进制表示,即 -32768。由于事物的设计方式,下一个数字由相应的下一个位模式表示,即:

biggest negative value = 0x8000 = -32768
0x8001 = biggest negative value + 1 = -32767
0xFFFF = biggest negative value  + 0x7FFF = -1
0xFFFE = biggest negative value  + 0x7FFE = 0xFFFF - 1 = -2
0xFFFD = biggest negative value  + 0x7FFD = 0xFFFF - 2 = 0xFFFE - 1 = -3

数字 0xFFFD 不会导致溢出,因为 -3 完全在 -32768 到 32767 的范围内。

任何短变量都是带符号的二进制补码,-3(十进制)的结果像任何二进制补码值一样计算。因此,要了解如何计算 -3(十进制)的结果,请查看 youtube 上的许多教程或任何相关教科书。

您的编译器似乎在将数字打印为 int 之前将 short 变量隐式类型转换为 int 值。为此,它必须执行所谓的符号扩展,因为它必须从 16 位带符号二进制补码中生成 32 位带符号二进制补码。就像任何十进制数一样,数字前有无数个零(例如 34 = 0034),负二进制补码前有无数个 1。所以编译器将最高有效位复制到左边。从 0xFFFD 中提取 0xFFFFFFFD,从 177775(oct) 中提取 37777777775(oct) 即 (00)1 111 111 111 111 101 (bin).

希望以上信息对您有所帮助。

but I don't know how to calculate the exact value,which is -3 in this case.

在计算机中表示整数的最常见方式是 2 的补码。

如果你有一个 n 位整数,你会得到这样的十进制值:

十进制值= - bn-12n-1 + bn-22n-2 + ... + b121 + b020 其中 bi 是位号 i.

的值

在你的例子中,你有一个 16 位变量。十六进制表示为 0xfffd,二进制为 1111.1111.1111.1101

代入公式你会得到:

小数= - 1*215 + 1*214 + ... + 1*22 + 0*21 + 1*20 = - 3

有关该主题的更多信息,请参阅 https://en.wikipedia.org/wiki/Two%27s_complement