'If condition understanding problem in c with syntax [closed]
if (!(c & ~0xFF))
c |= 0x0700;
Here what not than do what. Not able to understand this statement
[Sorry but my mind was just gone blur after writing too much code that i was not able to understand so a simple thing sorry for wasting your all times] Sorry once again
Solution 1:[1]
The behavior of the code is:
- If
c
, widened to at least anint
, has no bits above the first eight set, turn attempt to turn on the three bits that are on in0x0700
(bits 8, 9, and 10).
Equivalently:
- If
0 <= c && c < 256
, turn attempt to on the three bits that are on in0x0700
.
For simplicity, we assume an ordinary C implementation using two’s complement and a char
narrower than an int
. Then, in detail:
0xFF
has value 255. In its binary representation, the low eight bits are on, and all higher bits are off. The type of this constant isint
.~0xFF
inverts each bit. The low eight bits are off, and all higher bits are on.c & ~0xFF
performs a bitwise AND, but first, ifc
is narrower than anint
, it convertsc
to anint
. (Technically this depends on the ranks of the types, but “narrower” suffices in ordinary C implementations.) This conversion is important because it may act to extend the sign bit ofc
, discussed below. Ifc
is anunsigned int
or is wider than anint
, then~0xFF
is converted to a wider type. Because~0xFF
is a negative value and two’s complement is used, the result of this conversion still has all of its high bits set.- In the result of the bitwise AND, the low eight bits are off, and the only high bits set are those that were set in
c
(after conversion, if performed). !(c & ~0xFF)
tests this result. It is true if and only its operand is zero, meaning no bits are set inc & ~0xFF
.
If c
is negative, then, after conversion to an int
if necessary, it will have its sign bit set, so there will be a bit above the first eight set, so the test will be false. Otherwise, any conversion to an int
will not turn on any bits, so the test will be true if and only if c
has no bits above the first eight set. Therefore, the test is equivalent to “c
is greater than or equal to 0 and is less than 256.”
c |= 0x0700
performs a bitwise OR of c
with 0x0700
and stores the result in c
. If c
is wide enough, the bits that are on in 0x0700
will be turned on in c
. If c
is not wide enough but is unsigned, the bits that do not fit will be ignored. If c
is not wide enough but is signed, an implementation-defined conversion will be performed (or a signal will be raised), and the result could be anything.
So, what this code does is, if 0 <= c && c < 256
, turn on the bits that are on in 0x0700
, subject to the exceptional conditions described above.
Solution 2:[2]
if (!(c & ~0xFF)) c |= 0x0700;
~0xFF
is the same as 0xF...FFFFF00
or all bits 1
except the 8 least-significant ones.
(c & 0xF...FFFFF00)
is the most significant bits of c
followed by 8 0
bits
!(c & 0xFFFFFF00)
is either 0
(false) or 1
(true). It's false if the thing inside the parenthesis is not zero, true otherwise.
So, the full expression sets bits 8, 9, and 10 of c
if the first most-significant bits of the initial c
were all 0
(same as if ((c / 256) == 0)
or if ((c >> 8) == 0)
).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |