How does one make sense of a string of logical comparisons? - java

For example, how would one make sense of (true && false || (53 < 24));?
I'm aware that it evaluated to false I'm just curious as to how I would figure that out step by step.
Thanks!

You check a handy Java Operator Precedence table, which shows that && has higher precedence than ||, meaning that the expression is equivalent to:
((true && false) || (53 < 24))
Then you start evaluating:
((true && false) || (53 < 24))
↓
( false || (53 < 24))
↓
( false || false )
↓
false

Related

Simple logic not working or am I missing something?

I don't understand why the following class prints out:
true
false
I thought the output should be:
false
false
because this line prints false:
System.out.println((11 >= 1 || 11 <= 10) & (true == false));
so this line should also print false:
System.out.println(in1To10(11, false));
What am I missing here? Here's the class.
public class TestClass {
public static void main(String[] args) {
System.out.println(in1To10(11, false));
System.out.println((11 >= 1 || 11 <= 10) & (true == false));
}
public static boolean in1To10(int n, boolean outsideMode) {
if ((n >= 1 || n <= 10) & (outsideMode == false)) {
return true;
}
return false;
}
}
You want to test if value is in the range 1 to 10 ?
If thats the case, change (n >= 1 || n <= 10) to (n >= 1 && n <= 10)
( true )
( true ) & ( true )
(true || false ) & ( true ) <--- false == false is true!
if ((n >= 1 || n <= 10) & (outsideMode == false)) {
return true;
}
Look, is n >= 1? Yes, so it's true. true v p <-> true, so Java doesn't even check further. true /\ true <-> true so we enter if. return true;
Your code is in plain English:
if ((n is greater or equal to 1 OR smaller or equal 10) AND is the mode set to false)
return true
If you want it to return true if the number is between 1 and 10 incl, it would be:
if ((n is greater or equal to 1 AND smaller or equal 10) AND is the mode set to false)
return true
which in Java is:
if ((n >= 1 && n <= 10) && (outsideMode == false)) {
return true;
}
Also remember to use && and || as they are logical operators instead of | and & bitwise logical operators when dealing with boolean values.
so this line should also print false: System.out.println(in1To10(11, false));
No, this line should not print false. Although the first parameter, 11, indeed turns the expression n >= 1 || n <= 10 from your method into 11 >= 1 || 11 <= 10, which matches your other expression, the second parameter, false, turns outsideMode == false into false == false, while your other expression has true == false.
That is why the two outputs are different: the output from in1To10 is true because the comparison false == false produces true, while the output from main is false, because true == false produces false.
Note: your expression does not match its stated goal of checking if n is between 1 and 10, inclusive. You need to replace || with && to accomplish that.
I think you missed that in function in1to10, you are comparing (false == false) and in main you are comparing (true == false). And so is the result. Hope this helps.
Let's decompose the test in in1to10 :
Parameters : outsideMode = false; n = 11;
(n >= 1 || n <= 10) :=> (11 >= 1 || 11 <= 10) :=> (true || false) :=> so TRUE
outsideMode == false :=> false == false :=> so TRUE
In the end :
public static boolean in1To10(int n, boolean outsideMode) {
if ((TRUE) & (TRUE)) {
return true;
}
return false;
}
:=> return TRUE !
This will return true. How?
if ((n >= 1 || n <= 10) & (outsideMode == false)) {
return true;
}
You are passing 11 and false to the function.
When it goes to inside the first condition it will check that n >= 1 mean 11 >= 1 that is true, so it will not check n<=10. Again it will check the second condition and your outsideMode is false,
That will be like this, (true) & (true)
hence the whole condition will be true and the funciton will return true.
Again the second condition,
(11 >= 1 || 11 <= 10) & (true == false)
It will return false. How?
As 11 >= 1 is true and again it will not check 11 <= 10, and right side is false.
So the condition will be become like this,
true & false that will be false.

operator precedence && and ||

please ignore the question - its wrong
I am not sure if my question is issue is related to operator precedence- Just to rule out that I added additional bracket. My understanding is in that case that code in each bracket will be executed. So basically all the OR operation will happen and its output would be AND'ed to condition a.
I have below set of parameters a = true and c = 254 , b is not availble ( b is initialized to 0 -At any given time either b or c only is availble) . So for the above condition I am expecting if condition to result in true but it's resulting in false condition. Any reason why ? Also what is best way to debug such things as in where exactly condition is going wrong - any pointers
if ((a == true) && ((b == 460) || (b == 454) || (b == 455) ||
(c> 13568 && c< 14335) ||
(c> 10640 && c< 10655) ||
(c> 11296 && c< 11311) ||
(c> 25600 && c< 26111) || (c== 7825)))
First a is evaluated, if (a == true) evaluated to true, then only it will execute next && statement
((b == 460) || (b == 454) || (b == 455) ||
(c> 13568 && c< 14335) ||
(c> 10640 && c< 10655) ||
(c> 11296 && c< 11311) ||
(c> 25600 && c< 26111) || (c== 7825))
Inside this, it will check for any one condition which is true, and once it encounter any one statement true, it return from there.
For your condition to be true, a must be true, and in addition, at least one of the conditions on b or c must be true.
Therefore, if a==true and c==254, you will get false, since c is not within any of the ranges you allow, and, as you said, b is not available (which I'm assuming means it doesn't have one of the 3 values you allow).
It would be much simpler if the code is written in a more readable manner;
bool isEqualToAny(int valueToCheck, int[] listToCheckIn){
boolean isMatch = false;
(for item in listToCheckIn){
if (item == valueToCheck){
isMatch = true;
break;
}
}
}
bool isWithinRange(int valueToCheck, int min, int max){
return (valueToCheck > min && valueToCheck < max);
}
if ((a == true)
&& (isEqualToAny(b, int[]{460,454,455})
|| isWithinRange(c,3568,14335)
|| isWithinRange(c,10640,10655)
|| isWithinRange(c,11296,11311)
|| isWithinRange(c,25600,26111)
|| isWithinRange(c,10640,10655)
|| (c== 7825)))
In java8 you can use an array of Tuples to make #isWithinRange more like #isEqualToAny

Confusing with "&&" and "||"

What are the difference between case 1 and other two cases?
Case 1 : false && false || true
Case 2 : (false && false) || true
Case 3 : false && ( false || true )
&& has higher precedence than ||, so case 1 is equivalent to case 2.
See: http://en.cppreference.com/w/cpp/language/operator_precedence
Actually, case 1 and case 2 are equivalent expressions, but there can be a situation where the expression tree itself is different, like here:
true == false && false || true // A
true == (false && false) || true // B
// not the same!
Here they read as:
((true == false) && false) || true // A
(true == (false && false)) || true // B
because == has an even higher priority than &&.
&& is noted by * in boolean algebra, and || is noted by +. read it here.
The C/C++ operator precedence is derived usually from the mathematical precedences.
Case 1 : false && false || true => true
Case 2 : (false && false) || true => true
Case 3 : false && ( false || true ) => false
operation in brackets should always be executed before other operations.
case 2 : (false && false) || true => false || true => true
case 3 : false && ( false || true ) => false && true => false
case 1 : false && false || true => false || true => true
For case 3, short circuit evaluation causes the expression in the parenthesis after && to be ignored.
Short-circuit_evaluation

How to read this NOT operator?

I don't understand what the bolded part actually represents. Please correct me if I'm wrong.
30 does NOT equal to 30 is false OR NOT(17 equals to 17 (true) AND 20 is greater then 21(false)) // i don't get this one, do I just flip everything meaning like -1 before() so the statement would be:
17!=17(false) && 20<21(true). I'm lost here. Thanks for any advice.
boolean m;
m = ((30!=30) || !(17==17 && 20>21))
SOP(m);
true || false ?
The ! operator works on a single boolean type and returns the opposite of it's value.
Let's break this all down:
(30!=30 || !(17==17 && 20>21))
(false || !(true && false))
(false || !( false ))
(false || true ))
( true )
Let's consider the comparison to the left of the OR... that is 30 != 30. This is false. So
m = (false || !(17==17 && 20>21))
Next 17 is equal to 17,
m = (false || !(true && 20>21))
Next 20 is not > then 21, so false....
m = (false || !(true && false))
Next true and false is false... so
m = (false || !(false))
And that allows us to reach
m = (false || true)
So
m = true
m will equal true because...
30!=30 = false
17==17 = true
20>21 = false
so...
( false || ! ( true && false ) )
so...
( false || ! false )
so...
( false || true )
so..
true
I always find it helps to expand your calculations so to speak.
This condition will be true
boolean m = (A || B)
Here A is (30!=30)
and B is `!(17==17 && 20>21)`
Obviously, A wiil be false;
!(17==17 && 20>21) equals to !(true && false), equals to !false, equals to true.
Then m = (A||B) equals to (false || true) equals to true
Lets go through this step by step.
Initial problem:
m = ((30!=30) || !(17==17 && 20>21))
We know 30 equals 30 so the 30 != 30 is false:
m = ((false) || !(17==17 && 20>21))
Because it is an or statement, we can remove the false part:
m = !(17==17 && 20>21)
We know 17 is equal to 17 (or the world would be ending) and 20 is less than 21 so:
m = !(true and false)
True and false evaluates to false so we have:
m = !false
This makes m become true.

What am i missing in this java code?

if (array[i]<(char)65 || array[i]>(char)122 &&
array[i]>(char)91 || array[i]<=(char)96)
System.out.println("False")
in this code, when i try to assign character 'C' (which is 67 btw) to array[i] it still says false. I did the math and it's not supposed to print "false" as I stated below this line.
(67 < 65 = 0 || 67 > 122 = 0) = 0
(67 > 91 = 0 || 67 <= 96 = 1) = 1
So, this leaves us: 0 & 1 = 0 .
Any ideas?
With some formatting, your code is:
if ( array[i] < (char)65 || array[i] > (char)122 &&
array[i] > (char)91 || array[i] <= (char)96 )
System.out.println("False");
Since && has higher precedence than || (see Operators), this is equivalent to:
if ( array[i] < (char)65
|| ( array[i] > (char)122 && array[i] > (char)91 )
|| array[i] <= (char)96 )
System.out.println("False");
which, since && is short circuiting, is behaviorally equivalent to:
if ( array[i] < (char)65
|| array[i] > (char)122
|| array[i] <= (char)96 )
System.out.println("False");
which, since the last case covers the first, is logically equivalent to:
if ( array[i] > (char)122 || array[i] <= (char)96 )
System.out.println("False");
You'll print False whenever the value it greater than 122 or less than or equal to 96. 67 is less than 96, so you print False. As pointed out the in comments, there is a precedence to the operators. Rather than learning all the details (to predict cases like this), it's easier just to use enough parentheses.
The && is evaluated first, and then the || according to the Java Operator Precedence. So it gets evaluated the following way for 'C'
67>122 && 67>91 //false
67<65 || false //false
false || 67<=96 //true
if you uses parentheses it will solve this problem
if ((array[i]<(char)65 || array[i]>(char)122) &&
(array[i]>(char)91 || array[i]<=(char)96))
I think you may try this by using brackets ():
if ((array[i]<(char)65 || array[i]>(char)122) && (array[i]>(char)91 || array[i]<=(char)96))
System.out.println("False")
Also to note that && has higher precedence

Categories

Resources