The problem lies here:
addr[1] = (~currentAddr)/2+1;
You expect currentAddr
to 0xFFFF
, which is partially right. But, what you might have missed out is integer promotion rule, which makes it 0xFFFFFFFF
which is hexadecimal representation of -1
.
Now, there is simple math:
(~currentAddr)/2+1
is nothing but 0x01
or 1
, When you ~currentAddr>>1;
do this shift, it is again becoming -1
.
From
My aim is to have half the maximum of the variable, here 0x8000
If I understand you correctly, what you are trying to do is get the value which is equal to (Maximum value of Unsigned short)/2. If it is so, the proper way of doing it will be using USHRT_MAX
. Of course, you'll need to include limits.h
file in your source code.
Update:
Referring to your comments to David's answer, following changes works as expected. (You have tested, I haven't)
unsigned short c;
c = ~currentAddr;
unsigned short c_z = sizeof (c);
unsigned short ci;
ci = (c >> 1) + 1;
unsigned short ci_z = sizeof (ci);
addr[1] = ci;
Now, why this isn't promoted to integer as opposed to previous case
c = ~currentAddr;
It is promoted, but it yields an expected result because, as chux explainned (which I couldn't have done) it is (temporarily) promoted to int
during its operation, but resolved as (converted to) a unsigned short
again when it is stored in memory allocated to c
.
The C standard answers the question:
From the C99 standard: 6.5.16.1 Simple assignment
In simple assignment (=), the value of the right operand is converted to the type of the assignment expression and replaces the value stored in the object designated by the left operand.
In your case since both the LHS and RHS are of the same type, there is no need for any conversion.
Also, it says:
The type of an assignment expression is the type the left operand would have after lvalue conversion.
The same is specified by C11 6.5.16.1/2:
In simple assignment (=), the value of the right operand is converted to the type of the assignment expression and replaces the value stored in the object designated by the left operand.
Try this yourself:
int main(void)
{
unsigned short c;
unsigned short currentAddr= 0x0000;
c = ~currentAddr;
printf("\n0x%x", c);
printf("\n0x%x", (~currentAddr));
return 0;
}
This should print:
0xffff
0xffffffff