Logical OR precedence - c++

I have tried writing a loop that would refrain the user to enter a wrong kind of data (actually a boolean) into the program by using the || operator.
int Entrer()
{
int A;
do
{
cout<<"Entrez 0 ou 1."<<endl;
cin >> A;
}
while (A != (1 || 0));
return A;
}
Can somebody tell me why the program only accepts 1 and no 0 ?

do { ... } while (A != (1 || 0));
It should be while (A != 1 && A != 0);
Otherwise, A != (1 || 0) stands for A != 1 since (1 || 0) is evaluated before !=.

If you want to accept 1 and 0, you need to write the conditional as while(A != 1 && A != 0);. As your conditional written, it will evaluate the (1 || 0) first, and, as 1 is true and 0 is false, will evaluate to A != 1.

Related

How to Rewrite "IF CONDITION " for ON for 3min and OFF for 10min until 4Hr (240min)

I want shorten the if condition. How can I simplify this?
Where step = 1 to 240 in min
I want 1st 3 min ON= 1, second 10 min OFF = 0, It will repeated until 248 min
I wrote "if condition" which is consist of many condition. How to rewrite the code with simple expression
#include "udf.h"
DEFINE_PROFILE(ON_3min_OFF_10min_4Hr,thread,position)
{
face_t f;
real step,hf_3min,hf_10min;
hf_3min = 1; /*ON */
hf_10min = 0; /*OFF */
step=N_TIME;
begin_f_loop(f,thread)
{
if ((step<=3) || ((step>13) && (step<=16)) || ((step>26) && (step<=29)) || ((step>39) && (step<=42)) || ((step>52) && (step<=55)) || ((step>65) && (step<=68)) || ((step>78) && (step<=81)) || ((step>91) && (step<=94)) || ((step>104) && (step<=107)) || ((step>117) && (step<=120)) || ((step>130) && (step<=133)) || ((step>143) && (step<=146)) || ((step>156) && (step<=159)) || ((step>169) && (step<=172)) || ((step>182) && (step<=185)) || ((step>195) && (step<=198)) || ((step>208) && (step<=211)) || ((step>222) && (step<=225)) || ((step>235) && (step<=238)))
{
F_PROFILE(f,thread,position)=hf_3min;
}
else
{
F_PROFILE(f,thread,position)=hf_10min;
}
}
end_f_loop(f,thread)
}
From the bounds that you are checking, it seems your code is equivalent to:
if ((step - 1) % 13 < 3) {
F_PROFILE(f, thread, position) = hf;
} else {
F_PROFILE(f, thread, position) = hf2;
}
You need to be careful about the missing lower bound on the first condition, and the change of the bounds at the last 2 conditions, in case that's intentional.

Why is 'if(1 == 1 == 1 == 1 == 1);' TRUE but 'if(-1 == -1 == -1 == -1 == -1);' FALSE? [duplicate]

This question already has answers here:
Why comparing three variables together with == evaluates to false?
(2 answers)
Closed 2 years ago.
if (1 == 1 == 1 == 1 == 1)
std::cout << "right";
The code above shows 'right'.
if (-1 == -1)
std::cout << "right";
The code above also shows 'right'.
if (-1 == -1 == -1)
std::cout << "right";
The code above shows nothing. (It's because the if statement isn't TRUE I guess?)
I would like to know why this weird thing happens.
Because -1 is equal to -1 and this statement is always TRUE no matter how many times I repeat (as far as I know).
The conditions are evaluated from left to right, hence the following conditional statement
if (-1 == -1 == -1)
std::cout << "right";
is equivalent to
if (true == -1)//since -1 === -1
std::cout << "right";
equivalent to
if (1 == -1) // true is casted to 1
std::cout << "right";
equivalent to
if (false)
std::cout << "right";
So it's normal the statement std::cout << "right"; doesn't execute and you get nothing.
The conditions are done in their order so:
-1 == -1 == -1 == -1 == -1
becomes
true == -1 == -1 == -1 (because the first -1==-1 gives true)
becomes
false == -1 == -1 (because true==-1 gives false)
becomes
false ==-1
becomes
false
The same thing happen with 1==1==1==1==1 because 1==true (but not 1===true).
Let's look at your three examples.
1 == 1 == 1 == 1 == 1 would be equivalent to true == 1 == 1 == 1, since true == 1 is true (since true gets treated as a 1), you'd then get true == 1 == 1 which is then true == 1 and finally just true.
In your second example, -1 == -1, this is simply just true, since obviously -1 equals itself.
Now, for your last example, you have -1 == -1 == -1, which becomes true == -1. true is not equal to -1 since 1 is not equal to -1, so this is therefore false. As a result, the "right" does not get printed.
In C++ the evaluation order of the equality operator == is from left to right:
(-1 == -1) == -1
is evaluated to
1 == -1
which returns false
Your code hits on the rules for casting between int and bool.
Comparisons between int objects return a bool.
Comparisons between an bool and an int upcasts the bool to an int.
false cast to int is 0
true cast to int is usually 1
Your code does (1) for the first comparison and (2) for all comparisons after.
So, if we write your condition and evaluate it step by step:
(1 == 1) // == ... == 1
(true) // == ... == 1
int(true) // == ... == 1
1 // == ... == 1
true
versus if you compare -1:
(-1 == -1) // == ... == -1
(true) // == ... == -1
int(true) // == ... == -1
1 // == ... == -1
false

Issues with commutative property of && operator

The code below that I have been having strange issues with is meant to trim off the unused portion of an integer array, and then convert it into a string.
Ex:
_ABC__DE______ would become _ABC__DE.
The problems show up when the input is filled with the default character. ("_" in the example).
sLength is the length of the integer array chars
The problematic code:
int inputLength = sLength - 1;
while (chars[inputLength] == defaultChar && inputLength >= 0) {
inputLength--;
}
inputLength++;
Serial.println("input length: " + String(inputLength));
// (in)sanity check
Serial.println(inputLength);
Serial.println(String(inputLength));
Serial.println(inputLength <= 0);
Serial.println(0 <= 0);
Serial.println(inputLength == 0);
Serial.println(0 == 0);
if (inputLength <= 0) {
//reset cursor position
Serial.println("index set to 0");
index = 0;
} else {
output = "";
for (int i = 0; i < inputLength; i++) {
char c = charSet[chars[i]];
if (c == '_') {
c = ' ';
}
output += c;
}
done = true;
}
The output when given an array filled with defaultChar:
input length: 0
0
0
0
1
0
1
If I'm interpreting correctly, the output means that 0 > 0 and 0 =/= 0 on even lines, but 0 <= 0 and 0 = 0 on odd lines.
The workaround I've come up with is replacing
while (chars[inputLength] == defaultChar && inputLength >= 0) {
inputLength--;
}
with one of the following
while (inputLength >= 0 && chars[inputLength] == defaultChar) {
inputLength--;
}
.
while (chars[inputLength] == defaultChar) {
inputLength--;
if (inputLength < 0) {
break;
}
}
which both result in an output of:
input length: 0
0
0
1
1
1
1
index set to 0
Why does this change the result?
As far as I knew until now, the && operator was commutative.
Is there something that I am missing that makes
chars[inputLength] == defaultChar && inputLength >= 0
not equal to
inputLength >= 0 && chars[inputLength] == defaultChar?
If It's relevant, this is being run on an 328P Arduino Nano with the old bootloader using IDE 1.8.8
&& is not commutative. It evaluates the left operand first and then stops if the left operand evaluated to 0.
Your original code fails because at some point it evaluates chars[-1] (which causes undefined behaviour if chars is an array). The alternative version does not have that problem because it performs the >= 0 test before using inputLength as an array index.
&& is commutative in the sense that the result of a && b is same as the result of b && a. But the built-in operator && has a short-circuiting behavior. This means that if the result of a && b can be decided by evaluating the first operand alone, the second one is not evaluated.
So when the first operand is chars[inputLength] == defaultChar and inputLength is -1, you enter the territory of undefined behavior which means the behavior of the program is unpredictable. But with the workarounds, you avoid undefined behavior because of the inputLength >= 0 and inputLength < 0 checks and therefore the code works as intended.
As #PeteBecker notes: a() && b() is not commutative if either a() or b() has side effects.

Logic Error in TicTacToe game

here's a simple logic error I can't quite wrap my head around:
Why does the following statement always equate to true?
if ( (grid[i][0] && grid[i][1] && grid[i][2]) == ('X' || 'x') ) return true;
It works flawlessly for
if ( (grid[i][0] && grid[i][1] && grid[i][2]) == ('X') return true;
Do it like this:
create a function to check a character of being x:
bool isX(char c)
{
return c == 'X' || c == 'x';
}
and the you can write:
if ( isX(grid[i][0]) && isX(grid[i][1]) && isX(grid[i][2]))
return true;
That's because the expressions
'X' || 'x'
and
grid[i][0] && grid[i][1] && grid[i][2]
use the || and && operators between non-zero integer-typed values (because char is an integer type) and so they both evaluate to true.
To translate into C++ (or almost any other somewhat similar language, for that matter) that you want characters x, y and z to be equal to either of the characters c and C, you must compute
(x == c || x == C) && (y == c || y == C) && (z == c || z == C)
so apply that to your problem.
More importantly though, learn about boolean operators and programming in general before you try to tackle C++.
In the first case, it returns true because none of the grid elements has the value of zero. The && operator produces 0 or 1, depending on the values that you pass.
In the second case, it does not work as expected either: you wouldn't get an 'X' by &&-ing values together.
The proper way of checking if three items are equal to 'X' or not would be as follows:
if (toupper(grid[i][0]) == 'X'
&& toupper(grid[i][1]) == 'X'
&& toupper(grid[i][2]) == 'X') {
return true;
}
To generalize the concept of "win" in TiCTacToe, write a function that returns true when a sequence of three items with a specific step in each direction holds a sequence of a given character, like this:
bool isWin(int r, int c, int dr, int dc, char ch) {
return toupper(grid[r+0*dr][c+0*dc] == ch
&& toupper(grid[r+1*dr][c+1*dc] == ch
&& toupper(grid[r+2*dr][c+2*dc] == ch;
}
bool isWin(char ch) {
return isWin(0,0,0,1,ch)
|| isWin(0,0,1,0,ch)
|| isWin(1,0,0,1,ch)
|| isWin(0,1,1,0,ch)
|| isWin(2,0,0,1,ch)
|| isWin(0,2,1,0,ch)
|| isWin(0,0,1,1,ch)
|| isWin(2,0,-1,1,ch);
}

How to combine two if statements into one

Hi I have these two separate if statements, when put like so ;
if (powerlevel <= 0) // <--- ends up having no effect
if (src.health <= 0)
the_thing_to_do();
How do I combine these two if statements into one? is it possible? If so how?
If you want both statements to be true use logical AND
if(powerlevel <= 0 && src.health <= 0)
If you want either of the statements to be true use logical OR
if(powerlevel <= 0 || src.health <= 0)
Both of the above operators are logical operators
Use operator&& if you want both of them to be met (logical AND)
if(powerlevel <= 0 && src.health <= 0) { .. }
or operator|| if you want just one to be met (logical OR)
if(powerlevel <= 0 || src.health <= 0) { .. }
It depends if you want both to evaluate to true...
if ((powerlevel <= 0) && (src.health <= 0)) {
// do stuff
}
... or at least one ...
if ((powerlevel <= 0) || (src.health <= 0)) {
// do stuff
}
The difference being logical AND (&&) or logical OR (||)
Just an aternative if it is meaningful(sometimes).
Both true:
if (!(src.health > 0 || powerlevel > 0)) {}
at least one is true:
if (!(src.health > 0 && powerlevel > 0)) {}
Or if you don't want to use && you can use a Ternary Operator
#include <iostream>
int main (int argc, char* argv[])
{
struct
{
int health;
} src;
int powerlevel = 1;
src.health = 1;
bool result((powerlevel <= 0) ? ((src.health <=0) ? true : false) : false);
std::cout << "Result: " << result << std::endl;
}