我正在C学习,我对此转换有疑问。
short int x = -0x52ea;
printf ( "%x", x );
输出:
ffffad16
我想知道这种转换是如何工作的,因为它应该在测试中,我们无法使用任何编译器。谢谢
答案 0 :(得分:5)
我想知道这种转换是如何运作的
未定义的行为(UB)
short int x = -0x52ea;
0x52ea
是十六进制常量。它的值为52EA 16 ,或21,226 10 。它的类型为int
,因为它适合int
,即使int
为16位也是如此。 OP的int
显然是32位。
-
否定了-21,226的值。
该值已分配给可以编码-21,226的short int
,因此将此int
分配给short int
没有特殊问题。
printf("%x", x );
short int x
传递给...
函数,因此通过默认参数
促销活动并成为int
。因此传递了值为-21,226的int
。
"%x"
一起使用的 printf()
需要unsigned
个参数。由于传递的类型不是unsigned
(而不是具有非负值的int
- 请参见异常C11dr§6.5.2.26),结果是未定义的行为 (UB)。显然,你机器上的UB是打印32位2's complement -21,226或FFFFAD16
的十六进制模式。
如果考试结果不是UB,只需微笑并点头,然后意识到课程需要更新。
答案 1 :(得分:0)
这里的要点是,当一个数字为负数时,它的结构将完全不同。
16位十六进制中的1是0001
,-1是ffff
。最相关的位(8000
)表示它是一个负数(允许它是一个带符号的整数),这就是为什么它只能像32767(7fff
)那样正,而负数为-32768 (8000
)。
基本上,要从正变换为负,您将反转所有位和总和1. 0001
反转为fffe
,+ 1 = ffff
。
这是一个名为Two's complement的约定,因为在使用它时使用按位运算进行算术非常简单。