2

可能重复:
如何在 c 中打印带符号的十六进制

我正在尝试打印出十六进制数字。

我试图打印出来的变量是 type int i,当我:

printf("%06X", i);

如果数字是负数,它总是给我 8 位数字,如果是正数,它总是给我 6 位数字。

如果我将"%06", to"%04"或其他东西更改为负数,我总是得到 8 位数字。

4

2 回答 2

3

“%06X”中的“6”指定要打印的最小位数。如果需要更多以显示完整值,则转换将打印更多。如果值小于请求的最小位数,“0”表示使用前导零,而不是默认的空格。

你得到八位数,因为“X”说明符是一个unsigned int参数。没有负值unsigned int。您的 C 实现正在重新解释将负数编码为 un​​signed 的intint。例如,int值 -1 以 32 位二进制补码形式存储为 0xffffffff。因此,格式转换会看到unsigned int设置了高位的 an,并且它使用显示它们所需的所有数字。

您可以或应该进行几项更改:

首先,您不应该int为期望的说明符传递一个unsigned int。您应该使用强制转换将 转换为inta unsigned int,如(unsigned int) i.

其次,您应该传递要打印的值。如果您只想打印低六位十六进制数字,则可以使用带有 AND 运算符的掩码仅传递这些数字:printf("%06X", (unsigned int) i & 0xffffff)

或者,如果要打印带符号的十六进制值,则必须自己处理符号,如下所示:

if (0 <= i)
    printf(" %06X", (unsigned int)  i);
else
    printf("-%06X", (unsigned int) -i);

(后者假定i永远不会溢出足够大的负值-i。如果-i可能溢出,则可以进行简单的修改以获得所需的行为。)

于 2012-12-30T13:33:53.763 回答
0

负数使用2 的补码以二进制形式存储。这意味着,二进制中的负数具有前导 1。玩弄这个计算器以获得更好的感觉。

如果您要求printf使用%X该数字格式化数字,则该数字将被视为未签名。如果您处理负数的二进制表示而忽略 I 可能是负数的可能性,即忽略前导 1 作为负数的标志,那么您只能评估该数字实际上更大。

06部分告诉printf用前导 0 填充数字,最多六位数。当然,如果号码已经超过 6 位,这无关紧要。

于 2012-12-30T13:49:08.147 回答