When I run this simple code,
int main(int argc, const char * argv[])
{
bool digit(true);
std::cout << digit << " " << ~digit << std::endl;
}
The output is
1 -2
I was expecting 1 and 0 (for true and false). Am I missing something here?
~ performs bitwise negation. The operand is promoted (in this case) to int, and all the bits are inverted. 1 has a binary representation of 00....001, so this gives the binary value 11....110, which is interpreted (on most modern computers) as -2.
Use ! for logical negation.
~ is the bitwise not (or bit inversion) operator. The logical not operator is '!'.
cout << !digit;
Essentially:
1 -> 00000001
~1 -> 11111110
You need a logical not operator is '!'.You may try this;
cout << !(digit);
EDIT:-
Although I know its late but trying to improve my answer, ~ is the bitwise not operator. So if you write something like ~1000 then it would result out to be 0001
4 bits integer
1 -> 0001
find the complement by adding 1
0001 + 0001 = 0010 = 2
the complement is -2
Related
I have a question regarding the exercise 4.25 in C++ Primer:
Exercise 4.25: What is the value of ~'q' << 6 on a machine with 32-bit
ints and 8 bit chars, that uses Latin-1 character set in which 'q' has the
bit pattern 01110001?
I have the solution in binary, but I don't understand how this converts to int:
int main()
{
cout << (std::bitset<8 * sizeof(~'q' << 6)>(~'q' << 6))<<endl;
cout << (~'q' << 6) << endl;
return 0;
}
After executing, the following 2 lines are printed:
11111111111111111110001110000000
-7296
The first line is what I expected, but I don't understand how is it converted to -7296.
I would expect a lot larger number. Also online converters give a different result from this.
Thanks in advance for the help.
In order to answer the question, we need to analyze what types are the partial expressions and what is the precedence of the operators in play.
For this we could refer to character constant and operator precedence.
'q' represents an int as described in the first link:
single-byte integer character constant, e.g. 'a' or '\n' or '\13'.
Such constant has type int ...
'q' thus is equivalent to the int value of its Latin-1 code (binary 01110001) but expanded to fit a 32-bit integer: 00000000 0000000 00000000 01110001.
The operator ~ precedes the operator << so the bitwise negation will be performed first. The results is 11111111 11111111 11111111 10001110.
Then a bitwise shift left is performed (dropping the left 6 bits of the value and padding with 0-s on the right): 11111111 11111111 11100011 10000000.
Now, regarding your second half of the question: cout << (~'q' << 6) << endl; interpretes this value as an int (signed). The standard states:
However, all C++ compilers use two's complement representation, and as of C++20, it is the only representation allowed by the standard, with the guaranteed range from ā2Nā1 to +2Nā1ā1
(e.g. -128 to 127 for a signed 8-bit type).
The two's complement value for 11111111 11111111 11100011 10000000 on a 32-bit machine results in the binary code for the decimal -7296.
The number is not large as you would expect, because when you start from -1 decimal (11111111 11111111 11111111 11111111 binary) and count down, the binary representations all have a lot of leading 1-s. The leftmost bit is 1 for a negative number and 0 for a positive number. When you expand the negative value to more bits (e.g. from 32 to 64), you would add more 1-s to the left until you reach 64 bits. More information can be found here. And here is an online converter.
I don't understand how is it converted to -7296.
It(the second value) is the Decimal from signed 2's complement
~'q' << 6
= (~'q') << 6
= (~113) << 6
= (~(0 0111 0001)) << 6
= 1 1000 1110 << 6
= -7296
You may have forgotten to add some 0's in front of 113.
On a ones-complement platform, what would the following code print?
#include <iostream>
int main() {
int i = 1, j = -1;
std::cout << i+j << std::endl;
return 0;
}
I would suspect it would print "0" instead of "-0", but I can't seem to find anything authoritative.
Edit: To clarify, I am interested in how -0 would be printed, several people have suggested that in practice, the implementation of ones-compliment might not generate a negative zero with the above code.
In those cases, the following has been suggested to actually generate a -0:
#include <iostream>
int main() {
std::cout << ~0 << std::endl;
return 0;
}
The question still remains: what will this print?
First of all, just to clarify thing, crafting a negative zero using bitwise operations and then using the resulting value is not portable. That said, nothing specifies in the documentation of fprintf (thus, of std::basic_ostream::operator<<(int)) whether the sign bit in the representation of int corresponds to a padding bit in the representation of unsigned or an actual value bit.
As a conclusion, this is unspecified behaviour.
#include <iostream>
int main() {
std::cout << ~0 << std::endl;
return 0;
}
Indeed adding n to -n should give you a negative zero. But the generation of -0 doesn't happen in practice since 1's complement addition uses a technique called a complementing subtractor (the second argument is complemented and subtracted from the first).
(The idiomatic way of getting a signed floating point zero doesn't apply here since you can't divide an integer by zero).
Looking through the glibc source code, I found these lines in vfprintf.c:
532 is_negative = signed_number < 0; \
533 number.word = is_negative ? (- signed_number) : signed_number; \
534 \
535 goto LABEL (number); \
...
683 if (is_negative) \
684 outchar (L_('-')); \
So it would appear that the condition is signed_number < 0, which would return false for a -0.
as #Ysc mentioned, nothing in the documentation gives any specification to printing -0, so a different implementation of libc (on a ones-compliment) platform may yield a different result.
If we view the theoretical point of the one's complement. Since the zero is defined as (+/-)0 there will be two binary values for 0 if we have 4 Bit values the zero will be 0000 (+0) and 1111 (-0). As a result of this you always have to do a correction if an operation, addition or substraction, has a zero-crossing operation in it.
So for example if we do the following operation -2+6=4 the result will be calculated as followed:
1101 (-2)
+ 0110 (6)
------
1100 (add carry)
======
0011 (+3)
As you can see in the Bit operation the result is incorrect and is only the incomplete result. In this case we have to add a +1 to the value to get the correct result. To identify if the +1 has to be added we have to take a look at the add carry result. If the most left numer 1100 is a ONE than we have to add +1 to the result to get the correct result.
If we have a look at your example:
0001 (+1)
+ 1110 (-1)
------
0000 (add carry)
======
1111 (-0)
We see that the result will be -0 and this will be the final result because the left add carry bit is 0.
I'm kind of puzzled by this. I thought the ~ operator in C++ was supposed to work differently (not so Matlab-y). Here's a minimum working example:
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
bool banana = true;
bool peach = false;
cout << banana << ~banana << endl;
cout << peach << ~peach << endl;
}
And here's my output:
1-2
0-1
I hope someone will have some insight into this.
This is exactly what should happen: when you invert the binary representation of zero, you get negative one; when you invert binary representation of one, you get negative two in two's complement representation.
00000000 --> ~ --> 11111111 // This is -1
00000001 --> ~ --> 11111110 // This is -2
Note that even though you start with a bool, operator ~ causes the value to be promoted to an int by the rules of integer promotions. If you need to invert a bool to a bool, use operator ! instead of ~.
~ is bitwise NOT operator which means it flips all the bits. For boolean NOT, you should be using ! operator
I knew that ~ operator does NOT operation. But I could not make out the output of the following program (which is -65536). What exactly is happening?
#include <stdio.h>
int main(void) {
int b = 0xFFFF;
printf("%d",~b);
return 0;
}
Assuming 32-bit integers
int b = 0xFFFF; => b = 0x0000FFFF
~b = 0xFFFF0000
The top bit is now set. Assuming 2s complement, this means we have a negative number. Inverting the other bits then adding one gives 0x00010000 or 65536
When you assign the 16-bit value 0xffff to the 32-bit integer b, the variable b actually becomes 0x0000ffff. This means when you do the bitwise complement it becomes 0xffff0000 which is the same as decimal -65536.
The ~ operator in C++ is the bitwise NOT operator. It is also called the bitwise complement. This is flipping the bits of your signed integer.
For instance, if you had
int b = 8;
// b in binary = 1000
// ~b = 0111
This will flip the bits that represent the initial integer value provided.
It is doing a bitwise complement, this output may help you understand what is going on better:
std::cout << std::hex << " b: " << std::setfill('0') << std::setw(8) << b
<< " ~b: " << (~b) << " -65536: " << -65536 << std::endl ;
the result that I receive is as follows:
b: 0000ffff ~b: ffff0000 -65536: ffff0000
So we are setting the lower 16 bits to 1 which gives us 0000ffff and then we do a complement which will set the lower 16 bits to 0 and the upper 16 bits to 1 which gives us ffff0000 which is equal to -65536 in decimal.
In this case since we are working with bitwise operations, examining the data in hex gives us some insight into what is going on.
The result depends on how signed integers are represented on your platform. The most common representation is a 32-bit value using "2s complement" arithmetic to represent negative values. That is, a negative value -x is represented by the same bit pattern as the unsigned value 2^32 - x.
In this case, the original bit pattern has the lower 16 bits set:
0x0000ffff
The bitwise negation clears those bits and sets the upper 16 bits:
0xffff0000
Interpreting this as a negative number gives the value -65536.
Usually, you'll want to use unsigned types when you're messing around with bitwise arithmetic, to avoid this kind of confusion.
Your comment:
If it is NOT of 'b' .. then output should be 0 but why -65536
Suggests that you are expecting the result of:
uint32_t x = 0xFFFF;
uint32_t y = ~x;
to be 0.
That would be true for a logical not operation, such as:
uint32_t x = 0xFFFF;
uint32_t y = !x;
...but operator~ is not a logical NOT, but a bitwise not. There is a big difference.
A logical returns 0 for non-0 values (or false for true values), and 1 for 0 values.
But a bitwise not reverses each bit in a given value. So a binary NOT of 0xF:
0x0F: 00000000 11111111
~0x0F: 11111111 00000000
Is not zero, but 0xF0.
For every binary number in the integer, a bitwise NOT operation turns all 1s into 0s, and all 0s are turned to 1s.
So hexadecimal 0xFFFF is binary 1111 1111 1111 1111 (Each hexadecimal character is 4 bits, and F, being 15, is full 1s in all four bits)
You set a 32 bit integer to that, which means it's now:
0000 0000 0000 0000 1111 1111 1111 1111
You then NOT it, which means it's:
1111 1111 1111 1111 0000 0000 0000 0000
The topmost bit is the signing bit (whether it's positive or negative), so it gives a negative number.
I have written this C++ program, and I am not able to understand why it is printing 1 in the third cout statement.
#include<iostream>
using namespace std;
int main()
{
bool b = false;
cout << b << "\n"; // Print 0
b = ~b;
cout << b << "\n"; // Print 1
b = ~b;
cout << b << "\n"; // Print 1 **Why?**
return 0;
}
Output:
0
1
1
Why is it not printing the following?
0
1
0
This is due to C legacy operator mechanization (also recalling that ~ is bitwise complement). Integral operands to ~ are promoted to int before doing the operation, then converted back to bool. So effectively what you're getting is (using unsigned 32 bit representation) false -> 0 -> 0xFFFFFFFF -> true. Then true -> 1 -> 0xFFFFFFFE -> 1 -> true.
You're looking for the ! operator to invert a boolean value.
You probably want to do this:
b = !b;
which is logical negation. What you did is bitwise negation of a bool cast to an integer. The second time the statement b = ~b; is executed, the prior value of b is true. Cast to an integer this gives 1 whose bitwise complement is -2 and hence cast back to bool true. Therefore, true values of b will remain true while false values will be assigned true. This is due to the C legacy.
As pretty much everyone else has said, the bool is getting promoted to an integer before the complement operator is getting its work done. ~ is a bitwise operator and thus inverts each individual bit of the integer; if you apply ~ to 00000001, the result is 11111110. When you apply this to a 32-bit signed integer, ~1 gives you -2. If you're confused why, just take a look at a binary converter. For example: http://www.binaryconvert.com/result_signed_int.html?decimal=045050
To your revised question:
False to true works for the same reason as above. If you flip 00000000 (out to 32 bits), you get 11111111... which I believe is -1 in integer. When comparing boolean values, anything that is -not- 0 is considered to be true, while 0 alone is false.
You should use logical operators, not binary operators. Use ! instead of ~.