AlphaGoku
AlphaGoku

Reputation: 1020

Difference between ! and ~

I was implementing a simple state machine as follows:

typedef void V_V_StateFunc(void);
static V_V_StateFunc *const fpCurrentStateFunc[STATE_ELEM_SIZE]={

    &fn1,/*0*/

};

void Execute_StateMachine(const U8 bCurrent_StateIndex)
{
    if(bStateIndex == (~bInvert_StateIndex))
    {
        if(bCurrent_StateIndex <= STATE_ELEM_SIZE)
        {
            fpCurrentStateFunc[bCurrent_StateIndex]();
        }
        else
        {
            /*this should never enter*/
        }   
    }
    else
    {
            /*this should never enter*/
    }
}

void Update_State(U8 bNewIndex)
{
    bStateIndex=bNewIndex; //bStateIndex & bInvert_StateIndex are globals
    bInvert_StateIndex=(~bNewIndex);
}

In the function Execute_StateMachine(), if I check bStateIndex == (~bInvert_StateIndex), the value is always 0 and nevers enter the if statement, though bStateIndex=0 and ~bInvert_StateIndex=0 (i.e 0 == 0, which is true). Why is this happening?

If I change bStateIndex == (!bInvert_StateIndex),it enters the if statement.

What is the difference between ~ and ! here?

Upvotes: 2

Views: 277

Answers (6)

sh1
sh1

Reputation: 4751

! will change any value that is not zero to zero, and will change zero to one.

~ will perform a bitwise complement, switching every individual bit in the value between 0 and 1, but many of the possible values that are not zero will still not be zero after this operation. This means that x and ~x can both test as true (but they can't both test as false).

Also, because integer promotion occurs before the complement, it's impossible for any unsigned 8-bit integer to compare equal to the bitwise complement of another unsigned 8-bit integer, because the result of the complement is larger than will fit in an 8-bit type.

Upvotes: 2

Anands23
Anands23

Reputation: 780

! (Logical NOT operator) : It returns either true of false of an operation.The operation return type is always a boolean type.If the operation returns true, ! operator converts it to false and viceversa.
(eg) : !(1==2) returns TRUE whereas normally (1==2) returns false.

~ (Bitwise Unary Complement Operator) : This Unary operator works on binary values(0's and 1's) of the operand given.It processes the binary values and returns the output in operand's original type. (eg): ~(2) processes complement on the binary value of 2 (0010) and performs 2's complement operation on (0010) and returns the output in operand's original return type,(ie) the final output is -3.

Upvotes: 0

Lundin
Lundin

Reputation: 213902

I would guess it happens because of integer promotion. The ~ operator is a dangerous one to use, since its operand is integer promoted. So the promoted operand is of type int here and not U8 as you might think.

Meaning that if you pass the value 0xFF to ~, the result will be not be 0x00 as you might expect, but 0xFFFFFF00. Temporarily stored in a signed int.

Avoid this by always casting the result of the ~ operator to the intended type:

bStateIndex == (U8)(~bInvert_StateIndex)

Upvotes: 4

Chris Maes
Chris Maes

Reputation: 37742

the ! operator is the logical not operator; for example the expression

if (!variable)

is equal to:

if (variable == 0)

The ~ operator is the bitwise NOT operator; thus changing the value of each bit.

 char variable = 1;           // value: 00000001
 char variable2 = ~variable;  // value: 11111110 = 254  (as noted by @Lundin; value = 11111111 11111111 11111111 11111110 and then truncated to 11111110 upon assignment to char)

Upvotes: 8

mofed8461
mofed8461

Reputation: 26

! treat the value as boolean

if its 0 it will be 1

if its (anything but not 0) it will be 0

~ treat the value of each bit (do a 2's complement)

if its 7 (111b) it will be -8 (the extra -1 for 2's complement)

Upvotes: 0

chris01
chris01

Reputation: 12331

! is logical.

~ is bitwise.

chris

Upvotes: 1

Related Questions