short int和unsigned short的输出?

时间:2017-01-24 16:44:16

标签: c unsigned twos-complement

所以我试图解释以下输出:

short int v = -12345;
unsigned short uv = (unsigned short) v;

printf("v = %d, uv = %u\n", v, uv);

Output:
v = -12345
uv = 53191

所以问题是:为什么在这个程序在双补机上运行时会产生这个确切的输出?

将值转换为unsigned short时,哪些操作会导致此结果?

3 个答案:

答案 0 :(得分:2)

我的回答假定16-bit两个补码算术。

要查找-12345的值,请点击12345,补充它,然后添加1

12345 is 0x3039 is 0011000000111001.

补充意味着将所有1更改为0并将所有0更改为1&# 39,S:

1100111111000110 is 0xcfc6 is 53190.

添加一个:53191

在内部,-123450xcfc7 = 53191表示。

但如果你把它解释为无符号数,那么它显然只是53191。 (当您将有符号值分配给相同大小的无符号整数时,通常最终会发生的是您分配精确的位模式,而不转换任何内容。但是,稍后,您通常会以不同方式解释该值,例如你用%u打印它。)

另一种可能更容易思考的方法是16-bit算术"包裹"在2 16 = 65536。因此,您可以将65536视为0的另一个名称(就像0:0024:00都是名称午夜)。因此-1234565536 - 12345 = 53191

答案 1 :(得分:1)

转换规则,当将有符号整数转换为无符号整数时,由C标准定义,需要重复将TYPE_MAX + 1添加到该值。

来自6.3.1.3 Signed and unsigned integers

  

否则,如果新类型是无符号的,则转换为   重复加或减一个以上的最大值   可以用新类型表示,直到值在范围内   新类型。

如果USHRT_MAX为65535,则添加65535 + 1 + -1234553191

答案 2 :(得分:1)

看到的输出不依赖于2的补码,也不依赖于16或32位int。看到的输出是完全定义的,并且在罕见的1的补码或符号幅度机器上是相同的。结果取决于16位unsigned short

-12345在short的最小范围内,因此该任务没有问题。当short作为...参数传递时,会认为通常的促销活动为int且价值没有变化,因为所有short都在{{1}的范围内}。 int需要"%d",因此输出为int

"-12345"

明确定义了为无符号类型指定负数。使用16位short int v = -12345; printf("%d\n", v); // output "-12345\n" 时,unsigned short的值为-12345加上uv的最小倍数(本例中为65536),最终值为53191.

USHRT_MAX+1作为...参数传递,该值将转换为unsigned shortint,无论哪种类型包含unsigned的整个范围。 IAC,不会改变。 unsigned short"%u"匹配。它还匹配unsigned,其值可以表达为intint

unsigned
  

将值转换为unsigned short时,哪些操作会导致此结果?

施法并未影响最终结果。如果没有演员阵容,也会发生同样的结果。演员阵容可能有助于安静警告。