通常的算术转换:意外的输出

时间:2014-12-02 13:21:17

标签: c type-conversion

signed short Temp;
Temp = 0xF2C9;
Temp2 = 0x100;

unsigned char a;
a = (unsigned char)(Temp/((unsigned short)Temp2));

预期产量是多少?
根据我的理解,由于"通常的算术转换"第一个Temp应转换为unsigned shorta的结果应为0xF2,但我得到的回复0xF3表示使用有符号值执行操作Temp。请解释一下这种行为。

endianess在这种情况下是否也相关?

5 个答案:

答案 0 :(得分:1)

取决于INT_MAX >= USHRT_MAX

“常用算术转化”将Temp转换为(int) Temp。如果int宽于short,则只会“扩展符号”。

((unsigned short)Temp2)被提升为(int)((unsigned short)Temp2) (unsigned)((unsigned short)Temp2)

如果INT_MAX >= USHRT_MAX,则除以(int)/(int)完成。

否则,就像在16位系统上一样,除法完成为(int)/(unsigned),完成时为(unsigned)/(unsigned)


[编辑]

使用Temp(请参阅注释)初始化的

0xF2C9可能具有-3383的值(或者值{62}应该short不大于16位。)< / p>

(int)/(int), - 3383/256 - &gt; -13.21 ... - &gt; -13。 -13转换为unsigned char - &gt; 256 - 13 - &gt; 243或0xF3。

(假设16位int/unsigned(unsigned)/(unsigned),-3383转换为unsigned 65536 - 3383 - &gt; 62153. 62153/256 - &gt; 242.78 ... - &gt; 242. 242转换为unsigned char - &gt; 242或0xF2。

Endian-ness与此场景无关。


注意:正如@Jens Gustedt所指出的,Temp中的值是Temp为16位时的实现定义。

答案 1 :(得分:1)

不,首先算术运算符的所有参数都是提升,即窄类型,例如short被转换为int。 (至少在所有常见架构上)。

假设系统上short为16位宽,Temp的初始化是实现定义的,因为0xF2C9的值不适合该类型。最有可能是负值。然后,为了计算,该负signed short值被提升为int。除法的结果是负值,然后转换为unsigned char

答案 2 :(得分:0)

整数除法使用&#34;截断为零&#34;,因此该除法的结果为F3,即-13,而不是F2,即-14。如果你用十进制表示法计算结果,那么结果将是-13.21然后你会减少.21。

答案 3 :(得分:0)

“问题为什么整数已签名”

“根据我对”通常的算术转换“的理解,首先应该将Temp转换为无符号的短...” NO 。你错了。签名的短临界值具有高位设置,因此是负的。转换为int时,该位扩展到左侧。签名的短Temp2没有高bt设置;演员(无符号短片)没有效果;它被转换为积极的int。负int现在除以正int,导致负值。

在将Temp2转换为int时,您不希望扩展符号位。使用:

a = (unsigned char)(((unsigned short)Temp)/Temp2);

(我没有测试它;只是理论)

答案 4 :(得分:0)

Jens,Paul和Mch,

感谢您的澄清。但根据ISO / IEC 9899第6.3.1.1节

The rank of any unsigned integer type shall equal the rank of the corresponding
signed integer type, if any.

并按照6.3.1.8通常的算术转换&#34;以下规则应适用。

If both operands have the same type, then no further conversion is needed.

Otherwise, if both operands have signed integer types or both have unsigned
integer types, the operand with the type of lesser integer conversion rank is
converted to the type of the operand with greater rank.

**Otherwise, if the operand that has unsigned integer type has rank greater or
equal to the rank of the type of the other operand, then the operand with
signed integer type is converted to the type of the operand with unsigned
integer type.**

Otherwise, if the type of the operand with signed integer type can represent
all of the values of the type of the operand with unsigned integer type, then
the operand with unsigned integer type is converted to the type of the
operand with signed integer type.

Otherwise, both operands are converted to the unsigned integer type
corresponding to the type of the operand with signed integer type

所以根据上面提到的规则3,第一个签名短(整数类型)应该转换为 unsigned short (整数类型),然后应该执行算术运算结果应该是0xF2。