Anna
Anna

Reputation: 571

What is the difference between ~~x and !!x in C?

I am trying to check if any bit of an int x equals to 1, and the answer is !!x. I googled a bit and didn't find anything about why this is correct.

So say if I have a number x is 1010. What would !x be? What is the different between !x and ~x?

Upvotes: 3

Views: 2091

Answers (5)

Vineet Kapoor
Vineet Kapoor

Reputation: 8289

! : is a logical operator, which when operated gives only true or false as result. It converts true to false and false to true.
~ : is a bit-wise negation operator i.e. if a particular bit of some value is 0, it flips that bit to 1 and vice versa. Please note, it doesn't operate on the value as a whole, it only operates only on a bit.

In C, only numeric value 0 (i.e. 1-byte binary equivalent: 00000000) is logically false, everything else is true. Any value with even one of the bit equal to 1 in its binary equivalent is true. So,

/*Use and explanation of !x*/

int x = 1; //binary equivalent: 00000001 is logically true. it can be checked as follows
if (x) // if statement coerces x to boolean equivalent which is true.
    printf("%d is true", x);

The printf statement in above code snippet will be executed.

Now, when not logical operator is used on x (i.e. !x) the result is false as x ( =1 ) is logically true. Using it two times (i.e. !!x) will make it true again.
NOTE: using it first time caused two things

  1. Caused type conversion of value 1 to boolean equivalent(i.e. true).
  2. Changed the boolean (from step 1) to its opposite (i.e. false).

So, basically not logical operator can be used to check if something is true or false. Using it twice returns actual boolean equivalent of the value being checked.

/*Use case of ~x (bit-wise negation operator)*/
int x = 1; //binary equivalent: 00000001
int y = ~x; //Now, y will be ~x i.e. 11111110. it can be checked as follows.

printf("%d: value after operation of bit-wise operator", y);
//The printf statement will print decimal equivalent of 11111110 i.e. -2.

y = ~y; // i.e. y = ~~x, this will again flip the bits and make y equal to 1 i.e. 00000001.
printf("%d: value after double operation of bit-wise operator", y);

So, when it is required to check whether any of the bit in some value is 1 or not, basically it implies to check whether that value is logically true or not. And that can be checked using if statement (as shown above) or using even number of logical not operators, as shown below

int x = 1;
if(!!x)
  printf("x is true");

Upvotes: 0

unwind
unwind

Reputation: 399793

I am trying to check if any bit of an int x equals to 1, and the answer is !!x [...]

No, "the answer" (i.e. the proper way to write this check in C) is simply x != 0. That's much clearer, and doesn't make the reader think. Using two logical inversions computes the same value, but is much less clear.

Quoting the draft C11 spec, we have:

The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int. The expression !E is equivalent to (0==E).

So, there really isn't any difference.

Also, regarding negative zero, the standard requires that

For any integer type, the object representation where all the bits are zero shall be a representation of the value zero in that type.

So, checking for "all bits zero" for an integer really is the same as comparing to (non-equality to) 0.

Upvotes: 1

Sourav Ghosh
Sourav Ghosh

Reputation: 134286

! is a logical operator which takes the value of the operand of scalar type.

To quote C11, chapter §6.5.3.3, Unary arithmetic operators

The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int. [...]

OTOH, ~ is a bitwise operator which performs bitwise negation of the operand of integer type.

Related,

The result of the ~ operator is the bitwise complement of its (promoted) operand (that is, each bit in the result is set if and only if the corresponding bit in the converted operand is not set). The integer promotions are performed on the operand, and the result has the promoted type. [...]

For example, consider binary number 10.

  • !10 is 0.
  • ~10 is 01.

EDIT:

FWIW, is you use !!, the result you can get is either 0 or 1. OTOH, is you use ~~, you get back the original value of the operand.

Upvotes: 5

P45 Imminent
P45 Imminent

Reputation: 8591

The range of possible values of !x are 0 and 1.

~ (the bitwise complement) has the same range as its domain.

So ~~x will recover x, but !!x will not necessarily do that.

Upvotes: 1

pablo1977
pablo1977

Reputation: 4433

The NOT logical operation in C is represented by the operator !.
In C every null value means FALSE (like 0, 0.0 or the null pointer constant NULL). OTOH, every non-null is considered as meaning TRUE.
The logical negation makes an inversion of the logical value, thus converting every non-zero value in the integer value 0, and every zero value is converted in the integer value 1.
Then, a double negation only can be 0 or 1.

Now, if an object represents an arithmetical value, all its bits are 0 if and only if the value is 0 or 0.0. So the negation of such an object is equal to !0, that is, 1. Besides, if an object like 10101010, whose bits are not all 0, is just a non-null value, so its negation is 0 (that is !10101010 == 0).

Finally, you have !!0 == 0 and !!(non-zero-value) == 1.

The bitwise negation in C is represented by the operator ~.
In this case, the action of negation is done on each separated bit.
For example: ~11100111 == 00011000.

So, if you apply the bitwise negation operator twice, the original value is recovered: ~~x == x.

Upvotes: -1

Related Questions