If statement without '&&' works? [duplicate] - c++

This question already has answers here:
Comparing a variable to a range of values
(7 answers)
Closed 3 years ago.
int n = 5;
if(2<=n<=20)
{
cout << "hello";
}
In the above code, it does not give an error, it runs successfully and gives "hello" as output.
But we have to use && in this kind of equation.
Can anyone explain this?

<= is left-associative in C++, so the expresion is parsed as ((2 <= n) <= 20). 2 <= n is of type bool, which can implicitly convert to int: true converts to 1 and false converts to 0.
Both of these are <= 20, so the condition is effectively always true.
Note that the above assumes n is an int or another primitive numerical type. If n is a user-defined class with operator <= overloaded, the associativity bit is still true, but the part about implicit conversions may or may not apply, based on the return type and semantics of that overloaded operator.

2<=n<=20 will be executed as (2<=n)<=20.
2<=n results in 0 or 1, depending on the value of n.
0<=20 and 1<=20 are true, so the cout will be executed, independent of the value and type of n.
n could be an object of a class with overloaded operators where 2<=n results to something (object to a class or a value >21), which compared with <=20 results to false. In this case there would be no output.

You probably mean
if (2 <= n && n <= 20)
C++ and C group 2 <= n <= 20 as (2 <= n) <= 20; the sub-expression is either 0 (false in C++) or 1 (true), which are both less than or equal to 20, hence the entire expresion is 1 (true). This is true for any primitive non-pointer type n, including a floating point NaN.

The first comparison 2 <= n is evaluated first. This returns true, which is convertible to an int. From conv.integral#2:
If the source type is bool, the value false is converted to zero and the value true is converted to one.
Once true is converted to 1 or 0, the next comparison is 1 <= 20 or 0 <= 20 which is always true. Hence the output.

Related

Assigning strlen(s) value to an integer is varying the output, WHY? [duplicate]

This question already has answers here:
c++ vector size. why -1 is greater than zero
(3 answers)
Closed 1 year ago.
char s[100];
cin>>s;
int x=strlen(s);
if((x-2)>=9)
cout<<s[0]<<x-2<<s[x-1]<<endl;
else
cout<<s<<endl;
output for inputting 'a' is 'a' BUT
char s[100];
cin>>s;
if((strlen(s)-2)>=9)
cout<<s[0]<<strlen(s)-2<<s[strlen(s)-1]<<endl;
else
cout<<s<<endl;
OUTPUT of this program for same input 'a' is a18446744073709551615a.
Just assigning strlen(s) value to an integer is avoiding the problem to happen. WHY ??
From where is that garbage value of 18446744073709551615a coming from, and if the "if" condition is being compiled in second case then also , why?
When you input a, strlen will return unsigned (size_t) 1. 1 - 2 will not be -1 but wrap around at 0 and give you a very large unsigned integer (18446744073709551615 in your case).
strlen returns size_t - an unsigned type.
According to integral conversion rules, the type of strlen(s)-2 remains unsigned, which overflows for any strlen(s) less than 2, wrapping around and giving a large positive value (264-1 in your example).
When you first assign strlen(s) to an int variable, the value is converted to type int and the result of 1-2 becomes -1. You can achieve the same by casting strlen(s) to int:
if ((static_cast<int>(strlen(s))) - 2) >= 9) ...
Or just move -2 to the other side of the comparison:
if (strlen(s) >= 9 + 2) ...

Operator !! producing unexpected result

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++.

Double inequality while comparying three floating point numbers [duplicate]

This question already has answers here:
Comparing a variable to a range of values
(7 answers)
Why can't we do three-way comparison in C++? [duplicate]
(6 answers)
Closed 1 year ago.
Can somebody tell me why the following does not work?(I mean no output)
if(0.0001<0.001<0.01)
cout<<"hi\n"<<endl;
output: (blank)
While the following works:
if(0.0001<0.001 && 0.001<0.01)
cout<<"hi\n"<<endl;
output:hi
Because there is no magical n-ary < operator in C++.
0.0001 < 0.001 < 0.01
is parsed (since < is left-associative) as
(0.0001 < 0.001) < 0.01
and 0.0001 < 0.001 returns a value of type bool with value true. Now you have
true < 0.01
but according to the standard a true boolean has value 1 when converted to an integral type so you have
1 < 0.01
which is false.
If you mean simply you don't understand what 0.0001<0.001<0.01 means or why it doesn't evaluate to what you expect: C++ only defines binary versions of the comparison operators. So 0.0001 < 0.001 < 0.01 is not a single comparison of all three values; it's a comparison of two values and then another comparison of the third value with the result of the other comparison. I.e. 0.0001 < 0.001 < 0.01 is the same as (0.0001 < 0.001) < 0.01 is the same as true < 0.01 is the same as 1 < 0.01
If you mean why didn't C++ define operators to work the way you want here, it's because nobody saw enough value in making C++ work that way.
When you are using condition like
(0.0001<0.001<0.01)
It will check first 0.0001<0.001 i.e. true which returns 1 and now condition become
( 1< 0.01 )
which is false so returns 0 that's why printing nothing.

how to use logical operator directly into the user defined variables

#include <iostream>
using namespace std;
int main() {
// your code goes here
int x=1;
int y;
y=x&&10;
cout<<y;
return 0;
}
The output is 1.
How is the value stored in y? What is the operation of &&? Please explain.
This operation
y=x&&10;
is evaluated as:
x && 10
1 (int) && 10 (int)
true && true // Note any non-zero integer will be evaluated to true
true
Therefore
y = true
But y is an int, so then there is an implicit conversion from bool back to int, which results in y being 1.
If you write "a && b" then both of the variables a and b must equate to true, for the result of the expression to return true, otherwise false will be the result.
For integers, all values which are not zero are considered true. Both of your variables are non-zero so your expression returns true.
When a boolean is stored into an integer, true is expressed as 1 whilst false is expressed as zero.
This is why your application outputs 1.
y=0 only if you put 0 instead of 10 or assign 0 to x.
if the values of left hand operand and right hand operand both are non-zero y=1 as both represents true.
if one of the operand is 0 then y=0 as 0 represents false.

What does -->> actually do? [duplicate]

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.