Boolean logic expressions in Java - java

Can any kind soul please explain why
! (x < 0 && y < 0)
is not equivalent to the following two expressions
!(x < 0) && ! (y < 0) AND x > 0 && y > 0
In the first code doesn't it imply that, x is not less than 0 and y is not less than 0? and does it also not mean that x and y should be more than 0?
Any help is much appreciated!

In your two rewritten versions, you'd need OR (||) rather than AND (&&). This is true any time you invert an AND condition's component parts.
! (x < 0 && y < 0) is true if x is >= 0 and y is < 0. To get that same result in the other form, you'd need x >= 0 || y >= 0. (Note that it's >=, not just >, but the main point was the || rather than &&.)
As ernest_k points out, this is one specific application of De Morgan's laws.

Let's calculate the equivalent expression for ! (x < 0 && y < 0)
Note that if negation comes before &&, it becomes || and vice versa. so your expression would be equal to :
! (x < 0 && y < 0) ---> !(x<0) || !(y<0) ---> x>=0 || y>=0
it's like the figure bellow, colored area is the result of your expression :

In the first example both of the expressions in brackets ("(x < 0)" and "(y < 0)") have to be equal to "true" for the whole expression to become "false".
In the second example the first two expressions contain each one of the expressions, which are inside the brackets of the first example ("(x < 0)" and "(y < 0)"). So only one of these expressions being "true", can cause the whole expression to become "false" since everything is connected with AND operators.
You can set x=0 and y=-1 and try it out manually.
You also might be interested in having a look at https://en.wikipedia.org/wiki/De_Morgan's_laws

Related

40 If-Statements in a Loop, How to Avoid?

I am working with the library JInput to detect controller input in a java game. However, in order to get the direction the axis is moving, I use this:
gamePadContr.getComponent(Identifier.Axis.X).getPollData();
This gives me a decimal between -1 and 1, which tell the direction. I want the player to be able to move in more than just up, down, left, and right, so there are 40 if statements in my gameloop that check if the number is a certain set of numbers, and increasing the x and y coordinates accordingly. Here is an example:
if(x > .1 && x < .2 && y == 1){
// do stuff
} else
if(x > .2 && x < .3 && y == 1{
// do stuff
}
I have to check each one to make sure that most directions are accounted for.
My point is, 40 if statements is lagging. Is there anything I can do to optimize this?
A few edits to answer questions:
Didn't think it was relevant, but the reason increments of .1 have 40 different if statements is because I am checking the X and Y axis of the joystick. The possible combinations are (1, -1) (1, 1) (-1, 1) (-1, -1), giving me negatives and positives in 40 different combinations at increments of .1. (I don't know if that made sense.
//do stuff is just increasing the x and y coordinates of the player by certain amounts.
The best approach might be to discover a rule whereby you can directly compute the player's coordinate change directly from the joystick coordinates. For that, we would need details of what // do stuff is for each branch.
Another possibility, which is good if you don't have a simple relationship, is to convert your tests to a look-up by transforming the x and y values to array indexes
int xIndex = (int) (10 * x + 10); // an int between 0 and 20
int yIndex = (int) (10 * y + 10); // ditto
Then you can look up the player's coordinate changes in a 2-D array that you compute once ahead of time. More generally, you could have an array of Runnable objects, look up the appropriate Runnable based on the indexes, and run() it.
P.S. If each joystick coordinate can fall into any of 20 different ranges, then you have 400 cases, not 40. That is, unless you are always ignoring one or the other of the axes.
One thing you can do is nest your conditions. Instead of
if (x > .1 && x < .2 && y == 1){doStuff();}
else if (x > .2 && x < .3 && y == 1){doStuff();}
else if (x > .1 && x < .2 && y == 2){doStuff();}
else if (x > .2 && x < .3 && y == 2){doStuff();}
you may want to consider:
if (y == 1){
if (x > .1 && x < .2){doStuff();}
else if (x > .2 && x < .3){doStuff();}
}
else if (y == 2)
{
if (x > .1 && x < .2){doStuff();}
else if (x > .2 && x < .3){doStuff();}
}
Now your code can skip all the if checks that it knows aren't true. Instead of having to check up to 20*20 = 400 if statements, the program only has to check up to 20+20=40 if statements in any given loop. You will still HAVE a ton of if statements - in fact, you'll have slightly more than you had before - but 90% of them will be skipped, and they'll each be shorter, so the program will run faster.
You can also reduce the number of checks in each if statement with clever ordering. If you already checked x < .5 and it was false, then you already know that x < .4 is false. For example:
if (y == 1){
if (x > .9 ){doStuff();}
else if (x > .8){doStuff();} // no need to check if it's less than .9 since the previous line covered that case
}

how to convert a python expression to a java expression?

I have the following expression in python:
if 0.85 < 0.81 / 0.83 < 1.15 :
//do something
When I put this in python there is no problem and it returns a boolean (true) but I don't understand what '/' is? because it looks like your dividing two booleans. What does this expression evaluation to in java?
In java,
if (0.85 < 0.81 / 0.83 && 0.81 / 0.83 < 1.15) {
//do something
}
// A better solution as mentioned by #Makoto
float f = 0.81/0.83
if (0.85<f && f< 1.15) {
//do something
}
In Python, all comparison operations have the same priority. It can be chained arbitrarily, e.g., x < y < z is equivalent to x < y and y < z. Refer to Python documentation: Expressions for the detailed description.
you might want to use and(&&) to get a True :
if (0.85 < 0.81 / 0.83 && 0.81 / 0.83 < 1.15) {
//do something
}
Going to the docs, the answer to your question is literally spelled out in these two sections (both on the same page):
https://docs.python.org/3/reference/expressions.html#operator-precedence
https://docs.python.org/3/reference/expressions.html#comparisons
The first section gives a table that states that / has higher precedence than <, so your expression is effectively 0.85 < (0.81 / 0.83) < 1.15, or 0.85 < 0.9759036144578315 < 1.15.
The second section states:
Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).
This means that your statement translates exactly as
double x = 0.81 / 0.83;
if(0.85 < x && x < 1.15) {
// ...
}
The key here is that with comparison chaining, each expression is only evaluated once. In this case that means computing the division only once. Of course the Java compiler would probably have optimized that out for you anyway.

Java difference between || and && in this example

I am making a counter between number ranges and not sure the correct way to do this. I have always used the || operator but reading some examples, I feel I should be using the && command. Here is my example problem...
if(value >= 1 || value <=10){
count1++;
}
else if(value >= 11 || value <= 20){
count2++;
// AND SO ON........
Or should I be using the && operator like
if(value >= 1 && value <= 10){
count1++;
}
else if value >= 11 && value <= 20){
count2++;
}
|| means "or".
&& means "and".
value >= 1 || value <= 10 makes no sense because it's always true. All numbers are 1 or more, or 10 or less. Some numbers are both, but that doesn't matter.
value >= 1 && value <= 10 makes far more sense. There's a limited range of numbers ([1..10]) for which both the first condition and the second condition are true.
|| is the or operator, so the condition value >= 1 || value <=10 is true for all values if you think about it. So, unless you want your counts to be meaningless, use && which is the and operator.

The operator < is undefined for the argument type(s) boolean, int

I am new to processing and I am having trouble with this. I keep getting an error message for the bolded part of the code below. Is my syntax wrong?
void block(int x, int y, int s, color tinto) {
fill(tinto);
for (int i = 0; i < 3; i++) {
triple(x, y+i*s, s, tinto);
}
if (0 < i < 3 && 6 < i < 9) { // HERE
tinto = 255;
}
else {
tinto = tinto - 200;
}
}
In Java, to check if a variable is in a range you have to divide the statement into two parts, like this:
if (0 < i && i < 3 && 6 < i && i < 9){
}
This specific code will never be true, however, because you're asking for it to be in two different ranges. Perhaps you meant to check for either range?
if (0 < i && i < 3 || 6 < i && i < 9){
}
Note the || or operator instead of the && and operator.
The syntax is not valid, and I think you're expression is wrong anyway. You say i has to be within a range AND within another. I think you mean to write that it could be between one OR the other.
Example of valid syntax: instead of 0 < i < 3, write i > 0 && i < 3.
Try this:
if ( (i > 0 && i < 3) || (i > 6 && i < 9) )
Note that the following (which is what you were trying to do apparently) will never be evaluated to true because it cannot be within both ranges.
if ( (i > 0 && i < 3) && (i > 6 && i < 9) ) // incorrect
This isn't valid java expression. Try:
if (0<i && i<3 && 6<i && i<9){
There are two different problems with this code snippet. First, you have defined the 'i' variable as in "int" inside of the for loop. This instance of 'i' is no longer defined once you exit that for loop -- so the if statement below does not refer to that instance. To overcome this, define 'i' before the for loop...
int i;
for ( i=0; i<3; I++ ) {
...
}
if ( i ...
which brings me to the second error. The syntax "0 < i < 3" is not correct. In c/c++ the operators are executed one at a time ... so in this case the first "<" operator will be evaluated as "0 < i" and the result will be a Boolean (which will always be 'true' in your particular code snippet). But the important point is that the result is a Boolean. Next the code will attempt to evaluate that result with the next part of the statement -- "true < 3", which just doesn't make any sense, and so that receives a compiler error.
In your code snippet, there is no exit to the for loop until the value of i reaches 3, so this second "if" statement is unneeded. But if you did want to test to see whether i was between 1 and 2 (inclusive), then you would have to break those up into individual tests...
if ( 0 < i && i < 3 ...
Lastly ... if the value of i is between 1 and 2 (inclusive), then it cannot also be between 7 and 8 (inclusive) .. therefore the if statement as you coded it will always be false even after we correct the syntax.

RangeCheck with Positive and Negative Numbers

I'm working on a small game which has a graph. The idea is I do an action whilst the target location (designated by upper and lower bounds) has no been met (within 0.5). For example, if I target (7,7), the loop should stop when x and y are (both in this case) between 6.5 and 7.5.
However, having something such as the following condition has presented me with a problem when presented with negative numbers:
while ((X < tarX-0.5 || X > tarX+0.5) && (Y < tarY-0.5 || Y > tarY+0.5))
For example: if I have the target (-7,-7) then the loop will stop when ONE of the x or y values is in the range, not both.
Basically, I had the idea of having four different loops depending on whether x or y was positive. But I'm wondering if there's an easier way? (I did try to use Math.abs() to counteract the negative numbers, which worked but something destined for (-3,-3) could still then stop at (3,3))
loop should stop when x and y are (both in this case) between 6.5 and 7.5.
while (!(x >= 6.5 && x <= 7.5 && y >= 6.5 && y <= 7.5)) {
...
}
Applying De Morgan's Law, the above is equivalent to
while (x < 6.5 || x > 7.5 || y < 6.5 || y > 7.5) {
...
}

Categories

Resources