How do i make program which outputs NOT(x)?
Example:
- 12 to 3
- 0 to 1
- 2 to 1
explained:
- 1100 to 0011
- 0 to 1
01 to 10
printf("%i\n%i\n%i\n", ~12, ~0, ~2);
Prints:
-13
-1
-3
printf("%i\n%i\n%i\n", !12, !0, !2);
Prints:
0
1
0
How do i make program which outputs NOT(x)?
Example:
explained:
01 to 10
printf("%i\n%i\n%i\n", ~12, ~0, ~2);
Prints:
-13
-1
-3
printf("%i\n%i\n%i\n", !12, !0, !2);
Prints:
0
1
0
Your variadic arguments to printf are being promoted to int
, Think of it as storing your bits in variables first (int), then performing the bit-not on them:
int x = 12; // 0x0000000C
int y = ~x; // 0xFFFFFFF4
y is now a negative signed int value.
Change your format string and your values to unsigned and it may be closer to what you're looking for:
int main(int argc, char *argv[])
{
unsigned int x = 12;
unsigned int y = ~x;
printf("%u:%u\n",x,y);
return EXIT_SUCCESS;
}
Results:
12:4294967283
If you're looking for functionality to print actual "bit-ness" of the values an excellent starting point can be found here, since printf() has no native bit-binary print capabilities.
Finally, if all you're interested in flipping is the leading most significant non-zero bits be sure to special-condition your case when the input value is zero (0). You really need a "this many bits are significant to me" value to really do this right.
EDIT: A Tremendously Inefficient BitString: Obviously this will NOT work without a numeric type for the lead template argument. Use at your own discretion (and peril).
template<typename T, size_t N=sizeof(T)*8>
std::string bit_string(T value, size_t maxbits=N)
{
static const char *one = "1";
static const char *zero = "0";
std::string result;
maxbits = std::min(maxbits, N);
for (size_t i=0;i<maxbits;i++)
{
result = ((value & T(1)) ? one : zero) + result;
value >>= 1;
}
return result;
}
Your first example works the way it does because of the two's complement binary notation for negative numbers.
For example, the value 12
will actually be represented as 0000000000001100
in a 16-bit integer, and most likely will actually be a 32-bit integer. A bitwise-not of this value is 1111111111110011
, and this is -13
in two's complement.
Your second sample code uses a boolean-not operator. C++ treats any non-zero value as true, and the value of "not true" is always false
, or the integer 0
. Similarly, the !0
means "not false" and will return -1
as C++'s "standard true" value. (This value is used because !0 == -1
in two's complement, and so !false
and ~false
are equivalent operations.)
So: what you are proposing to do is more complicated than you think. What you call "NOT(x)" is actually "the bitwise NOT of a binary number, truncated to the smallest number of significant digits, and interpreted as unsigned." That's not as simple as you make it sound!
The significant digits part is especially important. If all numbers are 8-bit unsigned, then "NOT(2)" is actually 253
not (as you say you require) 1
.
It's also interesting to note that your definition means that NOT is no longer reversible: NOT(NOT(12))
is not 12
, but would in fact NOT(12) = 3
and then NOT(3) =
0
.
So, in order to implement what you want:
sd
for later.)2 ^ (sd) - 1
For example, with the number 12
:
4
( 2 ^ 4 = 16)1111111111110011
2 ^ 4 - 1 = 15
which in binary is 0000000000001111
1111111111110011 AND 0000000000001111 == 0000000000000011
which is the result you wanted.Well, if you want to flip all of the bits in an int, you could subtract the value from int max
, or to flip a short, subtract from short max
... at least I think that's what you're asking.