I have a problem relative to some C++ code about the !! operator. It gives me an unexpected result and I don't understand why:
int x=-12;
x=!!x;
print("value=",x);
The output of this is 1. But i do not know how. Can anyone explain this ambiguous result?
!!x is grouped as !(!x).
!x is 0 if x is non-zero, and 1 if x is zero.
Applying ! to that reverses the result.
So, !!x can be viewed as a way of setting x to 1 if it's not zero, and remaining at 0 if it's zero. In other words x = !!x is the same as x = x ? 1 : 0.
... !(-12) kindly explain this expression.
It's "logical not of -12". In C++ numeric value 0 is false in logical way, and any non-zero value is true in logical way. This is how C and C++ evaluates numerical values in boolean context, like if (expression) ..., i.e. if (-12) exit(1); will exit your application, because -12 is "true".
When you typecast numeric value to bool type and then back to int, the true will become value 1, but most of the time you can avoid these conversions and use intermediate results of numerical calculations directly, where any non-zero value is "true".
So "not of true" is value false. I.e. !(-12) == false. And !false == true. And you convert the logical value "true" back to int, which will make x == 1.
The !!(numeric_value) is idiomatic way in C++ (and in C too) to "normalize" any numeric value into precisely 0 or 1 (and you may encounter it in source code of many applications).
The "logical" distinction is important, because C++ has also binary operators, where the calculation is working per individual bits, not with value as whole. In "binary" way the "!" operator sibling is ~. Similar example to yours with bit-complement operator x=~~x; would then result into original value -12, because every bit of x is flipped twice, ending with same value as it did start. So ~~x is not something to encounter in regular source, as it's basically "no operation" (contrary to !! which is "no operation" only if the original value was already 0 or 1).
Also this is sometimes source of bugs for people learning the language, as they forget about the distinction and write something like
if (4 & 2) { /* this is "and" so it should be true??? */ }
// it will be false, because in binary way 4&2 == 0
if (4 && 2) { /* this is logical "and" and will be "true" */ }
// because 4 is non-zero, 2 is non-zero, and "true and true" is "true"
I.e. binary operators are & | ~ ^ (and, or, not, xor), and their logical siblings are && || ! for "and, or, not", the logical "xor" doesn't have operator in C++.
Related
I am new to C++, I am trying to understand a piece of code written in C++, here px is an integer, Could please tell me, if the following line is
doing something like if statement. Is it saying if pos.x is equal to residues[n-1] put it in px or vice versa?
px = (res->pos.x == residues[n-1]->pos.x) & (res->pos.x == residues[n+1]->pos.x);
Thanks a lot for your help
The & in this expression is a bitwise AND operation.
It takes the result of the comparison in both of the parentheses and does a bitwise AND on them.
In the left parentheses, it compares the x value of res to the x value of residues[n-1]. A true result is pretty much 1 and false is 0, so it pretty much evaluates to either 1 or 0.
In the right parentheses, you have the same comparison but at index n+1 now. Same things apply.
If both parentheses are true, the bitwise AND evaluates to 1 (true), else 0 (false).
px is probably an integer that is either 1 or 0 and it will hold 1 if both of the comparisons were true in the expression, otherwise it will hold 0. (It acts as a Boolean)
This question already has answers here:
What is the "-->" operator in C++?
(29 answers)
Closed 8 years ago.
In the question What is the "-->" operator in C++? it asks what --> does and gives a link to a comp.lang.c++.moderated thread. scrolling down the thread a bit further found me this:
> There is no such operator in C++.
> It's just a combination of two operators: postfix decrement "--" and
> greater ">".
> That's why this example works.
> Try ( x --> 20 ) and you'll get no output in this case;)
Of course there is. It is described together with "runs to" operator:
#include <stdio.h>
int main()
{
int x = 10;
while( x -->> 0 ) // x runs to 0
printf("%d ", x);
}
What does the "runs to" operator actually do?
while( x -->> 0 ) // x runs to 0
This is actually a hybrid of the -- (post-decrement) and >> (bitshift right) operators, better formatted as:
while (x-- >> 0) ...
For this specific usage, with 0 on the right hand side, x is decremented with each loop iteration due to the postfix --, and the prior (pre-decrement) value is shifted right 0 bits by >> 0 which does nothing at all when x is non-negative, so the statement could be simplified to:
while (x--) ...
When x is 1 that's non-zero so found true for the purposes of the while test, then post-decrement reduces it to 0 and the loop executes for the last time (with x being 0 during that iteration); the next time while (x--) is checked with x already 0, the while loop terminates, with x left wrapping to the highest representable value for the unsigned type.
More generally, if you try to use >> on a negative value (e.g. x starts at 0 or a negative value great than INT_MIN, so x-- yields a negative value) the result is implementation defined, which means you have to consult your compiler documentation. You could use your compiler documentation to reason about how it would behave in the loop....
Relevant part of the Standard: 5.8/3:
The value of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a non-negative value, the value of the result is the integral part of the quotient of E1/2^E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.
BTW /- for Visual Studio, per http://msdn.microsoft.com/en-us/library/336xbhcz.aspx, the implementation defined behaviour is "No shift operation is performed if additive-expression is 0.". I can't find anything in the GCC manual about this (would have expected it here).
while( x -->> 0 ) // x runs to 0
No, the "goes to operator" is --> with only one > sign. It decreases x by one and then compares the result to zero.
The -- >> 0 "runs to operator" decreases x and then bitshifts the result rightward by zero. Bitshifting by zero does nothing for nonnegative x, otherwise it's implementation-defined (usually does nothing, but could be random). Zero bitshifted by zero is zero, which is interpreted as false, at which point the loop will terminate.
So it "works" but it's a terrible way of expressing a loop.
-- decrements but returns the value of the variable before it was decremented, >> shifts to the right by the right operand, which is 0 (a.k.a. a no-op), then it implicitly compares the result against 0.
i am trying to do some exercises, but i'm stuck at this point, where i can't understand what's happening and can't find anything related to this particular matter (Found other things about logical operators, but still not enough)
EDIT: Why the downvote, i was pretty explicit. There is no information regarding the type of X, but i assume is INT, the size is not described either, i thought i would discover that by doing the exercise.
a) At least one bit of x is '1';
b) At least one bit of x is '0';
c) At least one bit at the Least Significant Byte of x , is '1';
d) At least one bit at the Least Significant Byte of x , is '0';
I have the solutions, but would be great to understand them
a) !!x // What happens here? The '!' Usually is NOT in c
b) !!~x // Again, the '!' appears... The bitwise operand NOT is '~' and it makes the int one's complement, no further realization made unfortunately
c) !!(x & 0xFF) // I've read that this is a bit mask, i think they take in consideration 4 bytes in X, and this applies a mask at the least significant byte?
d) !!(~x & 0xFF) // Well, at this point i'm lost ...
I would love not having to skip classes at college, but i work full time in order to pay the fees :( .
You can add brackets around the separate operations and apply them in order. e.g.
!(!(~x))
i.e. !! is 2 NOT's
What happens to some value if you perform one NOT is:
If x == 0 then !x == 1, otherwise !x == 0
So, if you would perform another NOT, you invert the truth-value again. i.e.
If x == 0 then !!x == 0, otherwise !!x == 1
You could see it as getting your value between 0 and 1 in which 0 means: "no bit of x is '1'", and 1 means: "at least one bit of x is '1'".
Also, x & 0xFF takes the least significant byte of your variable. More thoroughly explained here:
What does least significant byte mean?
Assuming x is some unsigned int/short/long/... and you want conditions (if, while...):
a) You´ll have to know that just a value/variable as condition (without a==b or something)
is false if it is 0 and true if it is not 0. So, if x is not 0 (true), one ! will switch it to 0 and the other ! to something not-0-like again (not necessarily the old value, only not 0). If x was 0, the ! will finally result in 0 again (first not 0, then again 0).
The whole value of x is not 0 if at least 1 bit is 1...
What you´re doing is to transform either 0 to 0 or a value with 1-bits to some value with 1-bits. Not wrong, but... You can just write if(x) instead of if(!!x)
b) ~ switches every 0-bit to 1 and every 1 to 0. Now you can search again a 1 because you want a 0 in the original value. The same !!-thing again...
c and d:
&0xFF sets all bits except for the lowest 8 ones (lowest byte) to 0.
The result of A&B is a value where each bit is only 1 if the bits of A an B at the same position are both 1. 0xff (decimal 255) is the number which has exactly the lowest 8 bits set to 1...
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 ~.
Just a quick question
printf("%d", 99 || 44) prints "1" in C
print 99 || 44 prints "99" in perl
There are two different kinds of evaluation. Does each one have a name?
edit: i'm interested to know how this Perl evaluation is commonly called when compared to C. When you say "C example is X, and perl example is not X, but Y" which words would you use for X and Y. "short circuit" is not what i'm looking for.
Read here.
Binary || performs a short-circuit logical OR operation. That is, if the left operand is true, the right operand is not even evaluated. Scalar or list context propagates down to the right operand if it is evaluated.
In Perl the || and && operators differ from C's in that, rather than returning 0 or 1, they return the last value evaluated.
printf("%d", 99 || 44) prints "1" in C
That is because 99||44 returns true(only 99(which is non-zero) is evaluated due to the short-circuiting action of || ) whose equivalent is 1 hence printf() prints 1.
print 99 || 44 prints "99" in perl
..rather than returning 0 or 1, the last value evaluated(99 here) is returned.
As you note, the words you are looking for are not "short-circuit". Short-circuit evaluation means that in the expression
e1 || e2
if expression e1 is evaluated to something representing truth, then it is not necessary to evaluate e2. Both C and Perl use short-circuit evaluation.
I'm aware of the distinction you make in two different flavors of short-circuit OR, but in twenty years of working in programming languages I have never seen these things named. The Perl version is quite popular in dynamic languages, e.g., Icon, Lua, Scheme.
The Perl version is almost expressible in C:
e1 ? e1 : e2
Unfortunately this version may evaluate e1 twice, depending on the optimizer—and if e1 has side effects, or if the compiler can't tell if it might have side effects, then the compiler is required to evaluated it twice. This defect can be fixed by binding the value of e1 to a fresh local variable, but that requires a GNU extension.
The C behavior can be emulated in Perl by
!!(e1 || e2)
The C version uses || as the logical OR between the two values. Both 44 and 99 evaluate to true in C as they are not 0, so the result of an OR between them returns 1 (AKA true in C)
In that particular perl snippet, || is the null-coalescing operator, an binary which evaluates to the second argument if the first is null, otherwise evaluating to the first argument. Since 99 is the first argument and not null, it gets returned and printed.
EDIT: Thanks Evan for the clafication: The || operator in perl is not the null-coalescing operator, it returns the RHS if the LHS evaluates to false, other wise returning the LHS. // is the "proper" null-coalescing operator.
Here's the list of values in perl that evaluate to false (from wikipedia)
$false = 0; # the number zero
$false = 0.0; # the number zero as a float
$false = 0b0; # the number zero in binary
$false = 0x0; # the number zero in hexadecimal
$false = '0'; # the string zero
$false = ""; # the empty string
$false = undef; # the return value from undef
$false = 2-3+1 # computes to 0 which is converted to "0" so it is false
In Perl, 99 || 44 returns 99, because || is "short circuiting" and if its first argument is true in boolean context, it just returns it. print prints 99.
In C the result of || is logical, which passed to printf results either in 1 or 0. It's also short-circuiting, so 44 isn't even evaluated.
Both C and Perl refer to their respective || operators as a "logical OR" (as distinct from a bit-wise OR). There's no special name for Perl's behavior of returning the last value as opposed to 0 or 1.
In C, || is a Boolean operation. In Perl it is an integer type-agnostic operation which happens to treat the first argument as a Boolean value. That is the only distinction.