Reputation: 13
signed short Temp;
Temp = 0xF2C9;
Temp2 = 0x100;
unsigned char a;
a = (unsigned char)(Temp/((unsigned short)Temp2));
What will be the expected output?
As per my understanding due to "Usual Arithmetic Conversions" first Temp
should be converted into unsigned short
and result in a
should be 0xF2
, but I am getting the response 0xF3
which means operation is performed with signed value of Temp
. Please explain the behavior.
Is endianess also relevant in this scenario?
Upvotes: 0
Views: 109
Reputation: 13
Jens ,Paul and Mch,
Thanks for your clarification. But as per "ISO/IEC 9899 section 6.3.1.1
The rank of any unsigned integer type shall equal the rank of the corresponding
signed integer type, if any.
and as per 6.3.1.8 Usual arithmetic conversions" following rules should be applicable.
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
so according to the above mentioned rule 3 1st signed short (integer type) should be converted in to unsigned short (integer type) and then arithmatic operation should be performed and result should be 0xF2.
Upvotes: 0
Reputation: 153338
It depends if INT_MAX >= USHRT_MAX
The "Usual Arithmetic Conversions" convert Temp
into (int) Temp
. This will only "extend the sign" if int
is wider than short
.
((unsigned short)Temp2)
is promoted to (int)((unsigned short)Temp2)
or (unsigned)((unsigned short)Temp2)
.
If INT_MAX >= USHRT_MAX
, then the division is done as (int)/(int)
.
Otherwise, like on a 16-bit system, the division is done as (int)/(unsigned)
, which is done as (unsigned)/(unsigned)
.
[Edit]
Temp
, initialized with 0xF2C9
(see note), likely has the value of -3383 (or has the value of 62153 should short
unlikely be wider than 16 bits.)
With (int)/(int)
, -3383/256 --> -13.21... --> -13. -13 converted to unsigned char
--> 256 - 13 --> 243 or 0xF3.
(Assuming 16-bit int/unsigned
) With (unsigned)/(unsigned)
, -3383 is converted to unsigned
65536 - 3383 --> 62153. 62153/256 --> 242.78... --> 242. 242 converted to unsigned char
--> 242 or 0xF2.
Endian-ness in not relevant in this scenario.
Note: As pointed out by @Jens Gustedt, the value in Temp
is implementation defined when Temp
is 16-bit.
Upvotes: 1
Reputation: 25266
"The question asked why the integers are signed"
"As per my understanding due to "Usual Arithmetic Conversions" first Temp should be converted into unsigned short..." NO. You are wrong here. The signed short Temp has its high bit set, hence is negative. The bit gets extended to the left when converted to int. The signed short Temp2 does not have its high bt set; the cast to (unsigned short) has no effect; it is converted to a positive int. The negative int is now divided by the positive int, resulting in a negtive value.
In the conversion of Temp2 to int, you don't want the sign bit extended. Use:
a = (unsigned char)(((unsigned short)Temp)/Temp2);
(I didn't test it; just theory)
Upvotes: 0
Reputation: 78903
No, first all arguments to arithmetic operators are promoted, that is narrow types, such as your short
s are converted to int
. (at least on all common architectures).
Assuming short
is 16 bit wide on your system, the initialization of Temp
is implementation defined because the value of 0xF2C9
doesn't fit to the type. Most probably it is a negative value. Then, for the computation, that negative signed short
value is promoted to int
. The result of the division is a negative value, which then in turn is converted to unsigned char
.
Upvotes: 1
Reputation: 9804
integer division works with "truncation toward zero", so the result of this division is F3
, which is -13, instead of F2
, which is -14. if you calculate this in decimal represenation the result would be -13.21 and then you would cut the .21.
Upvotes: 0