I was working on making a game, and I was wondering why the construct with the == operator doesn't work while the lower one does. I used an NSLog message afterwards to test.
if (pipe.position.x == bird.position.x){ no idea why this doesn't work
if ((pipe.position.x <= bird.position.x) & (pipe.position.x > bird.position.x - 1)){
This is because one (or both) of the position.x's are a floating-point2 value with a non-zero difference1 between the two position values such that only the second condition is true.
Since p <= b is true for all values that make p == b true, to see why this works "unexpectedly" let's choose some values such that the expression p == b is false2 yet p < b is true and p > b - 1 is true.
Given p = 3.2 (pipe) and b = 3.7 (bird), as an example, then
p == b
-> 3.2 == 3.7
-> false
but
(p <= b) & (p > b - 1)
-> (3.2 <= 3.7) & (3.2 > 3.7 - 1)
-> (3.2 <= 3.7) & (3.2 > 2.7)
-> true & true
-> true
Instead, to detect when the bird "is crossing" the pipe, assuming that x increases to the right, consider
// The bird's head to the "right" of the pipe leading edge..
bird_x >= pipe_x
// ..but bird's butt is not to the "right" of the pipe trailing edge.
// (Also note use of the &&, the logical-AND operator)
&& (bird_x - bird_width <= pipe_x + pipe_width)
Of course, using a non-rectangle (or forgiving overlap) collision detection would lead to less frustrating flapping!
1 This issue occurs because there are some particular floating-point values (but there are no integer values) which can cause the observed effect.
First, reiterate the assumption that p is not equal to b, given that the first condition does not succeed. Let's suppose then that p <= b is written as p == b || p < b but since p == b is false , we can write it as p < b by tautology.
Since both clauses in the second condition are true (such that true && true -> true), we have the rules: 1) p < b is true, and 2) p > b - 1 is true.
Rewriting p < b as p - b < 0 and p > b - 1 as p - b > -1, and then replacing p - b with x yields: x < 0 and x > -1. However, there is no integer value of x which satisfies -1 < x < 0.
(In first section, where p = 3.2 and b = 3.7, x = (p - b) = 0.5 which satisfies the given constraints when x is not restricted to an integer value.)
2 With all above aside, it is possible for p and b to be "very close but different" floating-point values such that there is a non-zero difference between them - due to rounding, they may even be displayed as the same integer value! See How dangerous is it to compare floating point values? and related questions for the cause and "odd" behavior of such when using ==.
If this is the case then round to integer values and use an integer comparison, or; rely entirely on relational comparison such as shown in the proposed condition, or; use epsilon comparison for "nearly equal" of floating-point values.
if you choose abs(pipe.position.x) == abs(bird.position.x) the first condition may satisfy.
Related
These are the conditions:
if(x > 0)
{
y >= a;
z <= b;
}
It is quite easy to convert the conditions into Linear Programming constraints if x were binary variable. But I am not finding a way to do this.
You can do this in 2 steps
Step 1: Introduce a binary dummy variable
Since x is continuous, we can introduce a binary 0/1 dummy variable. Let's call it x_positive
if x>0 then we want x_positive =1. We can achieve that via the following constraint, where M is a very large number.
x < x_positive * M
Note that this forces x_positive to become 1, if x is itself positive. If x is negative, x_positive can be anything. (We can force it to be zero by adding it to the objective function with a tiny penalty of the appropriate sign.)
Step 2: Use the dummy variable to implement the next 2 constraints
In English: if x_positive = 1, then y >= a
However, if x_positive = 0, y can be anything (y > -inf)
y > a - M (1 - x_positive)
Similarly,
if x_positive = 1, then z <= b
z <= b + M * (1 - x_positive)
Both the linear constraints above will kick in if x>0 and will be trivially satisfied if x <=0.
Here's my Fibonacci code using python 3.5
z = 0
x = 0
y = 1
while z != 317811:
x = x + y
z = x
print (z)
y = x + y
z = y
print (z)
I am wondering why this prints to infinity when setting the condition to
z != 317811
but works when it is below this number like
z != 196418
or a number greater than this like
z!= 514229
I tried a different approach (z <= 317811) but it prints up to 514229.
Thank you for your time.
KD
You're only testing alternate Fibonnaci numbers as the stopping condition: 317811 is getting missed.
One fix would be to test both x and y.
this is just logical problem
you are printing two
z != 317811
for this condition
"z"
is updated twice once in first z assignment i.e z = x
but "z" again get updated at second assignment z = y and then "z" is not sutisfying the condition(z != 317811) and not equal to 317811 but it is now 514229
Note: it will always work for number being printed at the second steps as this value of Z will be compared in while condition in loop
You are increasing z value twice a loop, but only checking once.
What actually is happening is that z is increasing with the fibonacci serie. Last values of z are:
196418
317811
514229
But you are only checking the stop condition once every two assignment. In this case you are checking that 196418 != 317811 and 514229 != 317811, thus never matching it.
One possible fix could be to test if z != 317811 after the first print. Even if in this case I would prefer testing "<" instead of "!="
Is there a way I can test if an interval given by two attributes within a table intersetcs another one which is "hard-coded"? Let´s say we have a table
a | b
2 | 3
4 | 6
1 | 2
where the two attributes mark an interval. Now I want to get all the intervals that intersect e.g. {3, 5} (for now lets call those two numbers lower (l)- and upper(u)-bound). This should result in {{3}, {4, 5}}.
I already thought about an approach building a huge SQL-query that checks for every row to be returned for the following four cases:
a >= l && b <= u // attribute-given interval completely enclosed by bounds
a <= l && b <= u // attribute-given interval falls out to "the left"
a >= l && b >= u // attribute-given interval falls out to "the right"
a <= l && b >= u // bounds are completely enclosed by attribute-given interval
However I wondered if there´s a smarter approach using any built-in-function two perform such an intersection.
I´m using Oracle 11g for this.
Assuming that your interval pairs are ordered (i.e. a <= b for all rows) you could use this formula to check if intervals intersect:
SELECT *
FROM MyIntervals
WHERE LEAST(b, u) >= GREATEST(a, l)
The idea is to see if the smaller of the right sides of the two intervals is greater than the greatest of the left sides.
The formula above will return all rows where intervals overlap or touch. If you do not want touching intervals, use > in place of >=.
Use this code:
select *
from MyIntervals MI
where MI.A <= U
and L <= MI.B
This will get all the possibilities where your interval overlaps the leading edge, or the trailing edge of your target interval, or your interval completely contains, or is completely contained by your target interval.
This works when A <= B and L <= U since when the two ranges overlap in any way, the start of each range will always be less than the end of the other range. If they don't overlap, then there are only two situations where they won't, one is where A > U and the other is where B < L which can be rewritten as L > B. That is the don't overlap when (A > U) | (L > B), and they do over lap when NOT((A > U) | (L > B)). Applying De Morgan's Laws:
NOT((A > U) | (L > B))
= NOT(A > U) & NOT(L > B)
= (A <= U) & ( L <= B)
I am trying to verify that a variable is NOT equal to either this or that. I tried using the following codes, but neither works:
if x ~=(0 or 1) then
print( "X must be equal to 1 or 0" )
return
end
if x ~= 0 or 1 then
print( "X must be equal to 1 or 0" )
return
end
Is there a way to do this?
Your problem stems from a misunderstanding of the or operator that is common to people learning programming languages like this. Yes, your immediate problem can be solved by writing x ~= 0 and x ~= 1, but I'll go into a little more detail about why your attempted solution doesn't work.
When you read x ~=(0 or 1) or x ~= 0 or 1 it's natural to parse this as you would the sentence "x is not equal to zero or one". In the ordinary understanding of that statement, "x" is the subject, "is not equal to" is the predicate or verb phrase, and "zero or one" is the object, a set of possibilities joined by a conjunction. You apply the subject with the verb to each item in the set.
However, Lua does not parse this based on the rules of English grammar, it parses it in binary comparisons of two elements based on its order of operations. Each operator has a precedence which determines the order in which it will be evaluated. or has a lower precedence than ~=, just as addition in mathematics has a lower precedence than multiplication. Everything has a lower precedence than parentheses.
As a result, when evaluating x ~=(0 or 1), the interpreter will first compute 0 or 1 (because of the parentheses) and then x ~= the result of the first computation, and in the second example, it will compute x ~= 0 and then apply the result of that computation to or 1.
The logical operator or "returns its first argument if this value is different from nil and false; otherwise, or returns its second argument". The relational operator ~= is the inverse of the equality operator ==; it returns true if its arguments are different types (x is a number, right?), and otherwise compares its arguments normally.
Using these rules, x ~=(0 or 1) will decompose to x ~= 0 (after applying the or operator) and this will return 'true' if x is anything other than 0, including 1, which is undesirable. The other form, x ~= 0 or 1 will first evaluate x ~= 0 (which may return true or false, depending on the value of x). Then, it will decompose to one of false or 1 or true or 1. In the first case, the statement will return 1, and in the second case, the statement will return true. Because control structures in Lua only consider nil and false to be false, and anything else to be true, this will always enter the if statement, which is not what you want either.
There is no way that you can use binary operators like those provided in programming languages to compare a single variable to a list of values. Instead, you need to compare the variable to each value one by one. There are a few ways to do this. The simplest way is to use De Morgan's laws to express the statement 'not one or zero' (which can't be evaluated with binary operators) as 'not one and not zero', which can trivially be written with binary operators:
if x ~= 1 and x ~= 0 then
print( "X must be equal to 1 or 0" )
return
end
Alternatively, you can use a loop to check these values:
local x_is_ok = false
for i = 0,1 do
if x == i then
x_is_ok = true
end
end
if not x_is_ok then
print( "X must be equal to 1 or 0" )
return
end
Finally, you could use relational operators to check a range and then test that x was an integer in the range (you don't want 0.5, right?)
if not (x >= 0 and x <= 1 and math.floor(x) == x) then
print( "X must be equal to 1 or 0" )
return
end
Note that I wrote x >= 0 and x <= 1. If you understood the above explanation, you should now be able to explain why I didn't write 0 <= x <= 1, and what this erroneous expression would return!
For testing only two values, I'd personally do this:
if x ~= 0 and x ~= 1 then
print( "X must be equal to 1 or 0" )
return
end
If you need to test against more than two values, I'd stuff your choices in a table acting like a set, like so:
choices = {[0]=true, [1]=true, [3]=true, [5]=true, [7]=true, [11]=true}
if not choices[x] then
print("x must be in the first six prime numbers")
return
end
x ~= 0 or 1 is the same as ((x ~= 0) or 1)
x ~=(0 or 1) is the same as (x ~= 0).
try something like this instead.
function isNot0Or1(x)
return (x ~= 0 and x ~= 1)
end
print( isNot0Or1(-1) == true )
print( isNot0Or1(0) == false )
print( isNot0Or1(1) == false )
I have an if statement followed by several else if statements. All of the if/else if statements have an argument structured something like this:
if (100 <= x <= 149) //do this
else if (150 <= x <= 199) //do that
else if ...etc...
However, for some reason only the first if statement ever gets executed. X can be 200 and only the first if statement will be recognized.
I'm not sure why it isn't moving on to the next else if statement when X doesn't fit the argument of the preceding statement. Does this not work in Obj-C? Any help is appreciated. Thanks
You need to rephrase the statements like:
if (x >= 100 && x <= 149) {
} else if (x >= 150 && x <= 199) {
} ...
Your first if is evaluated like:
if ((100 <= x) <= 149)
Let's have a look how that evaluates:
If x = 200, then (100 <= 200) is true and thus evaluates to the value 1 (which means true). And then 1 <= 149 is also true.
If x has a value smaller than 100, for example 10, then (100 <= 10) is false and thus evaluates to the value 0 (which means false). Again, 0 <= 149 is true.
So regardless of the value of x, the whole expression will always be true.
C is not math, so
if (100 <= x <= 149)
is NOT the same as
if (100 <= x && x <= 149)
Which is what you meant. The former will be true always, because 100 <= x <= 149 becomes
((100 <= x) <= 149)
leaving two possibilities: (1 <= 149) or (0 <= 149). Both are always true.
Chained comparisons like these don't work in C-based languages. Or rather, they do, but not how you'd expect.
100 <= x <= 149 gets evaluated as (100 <= x) <= 149. If x is over 100, then (100 <= x) will evaluate to true, or 1. If x is under 100, it's false, or 0. In either case, 0 <= 149 or 1 <= 149 is true, so the overall expression is true.
To fix this, change your conditions to look like this:
if (100 <= x && x <= 149)
That will make it work as you expect.
The compiler sees an expression formulated from binary operators. The <= symbol is a binary operator, as are =, >=, ||, &&, and so forth.
Just as with arithmetic, there is an order of precedence that the compiler must follow, evaluating the expression formed around each binary operator.
In arithmetic, you are probably familiar with this, as with these two examples:
2+5*7 This evaluates to 2+(5*7) or 37, because multiplication has precedence over addition.
2+3+21 is evaluated in the order the terms are read from left to right, since there is no other precedence rule. It becomes (2+3)+21.
So 100<=x<=150 is an expression of a similar type, where the binary operators are all the same, and thus have the same precedence. Once again, this is resolved by evaluating it from left to right, so it becomes (100<=x)<=150. If x>=100 the term in parentheses evaluates to TRUE, which has a numeric value of 1. Since 1 is less than 150, the rest evaluates to 1<=150, or TRUE, if x is greater than or equal to 100. On the other hand, it also evaluates to TRUE if x is less than 100, because the second comparison becomes 0<=150, which is TRUE.
The other recommendations to break this down with parentheses are correct if you aren't sure of the order of precedence for binary operators: (100<=x) && (x<=150). You can also write it as 100<=x && x<=150 since the order of precedence for value comparisons is higher than for logical operators.
Because if (100 <= x <= 149) is the same as if(1<=149) if you give 200 or another number to x. And that is correct always.
For example.
x=1
100<=1 is false so you get if(0<=149) which is true
x=200
100<=200 is true so you get if(1<=149) which is true
So you always get true for it.
So you must do it in another way, like this
if(x>=100 && x<=149) ...
Adding some additional parenthesis may help.
if ((100 <= x) && (x <= 149)) //do this
I don't think you can write math functions like this in objective-c... Try separating them and combining with an && statement:
if ( (100 <= x) && (x <= 149) ) { // "&&" = and, "||" = or, other math comparison operators are: <=, >=, <, >, ==, != (!= is does not equal))
//do this
} else if ( (150 <= x) && (x <= 199) ) {
//do that
} else if ...etc...
You've already got a lot of answers, but I'll add one more to cover one other possible point of confusion.
In C & Obj-C the boolean (and character) types are treated as integer types, which is not the case in call languages. So expressions like 'z' * true make perfect sense!
(Modern) C uses the type _Bool for boolean, which is defined to be large enough to hold 0 & 1. Cocoa uses the type BOOL for boolean, which is defined as signed char. CoreFoundation uses the type Boolean which is defined as unsigned char. All three define YES/true as 1 and NO/false as 0, while C itself treats any non-zero value as true.
The relation operators such as <, <= etc. are defined to return the int (yes, none of the booleans, not even _Bool) value 0 if the relation is false, and the int value 1 if the relation is true.
Given this and the left-to-right associativity of relational operators your:
if (100 <= x <= 149)
is parsed as:
if ((100 <= x) <= 149)
then 100 <= x evaluates to the int value 1 if x is greater than or equal to 100, otherwise it evaluates to the int value 0, so we get:
if (1 <= 149)
or
if (0 <= 149)
both of these evaluate to 1 so we get:
if (1)
and the if statement branches to the "then" branch if it's expression is non-zero.
It may be surprising, but the whole statement is evaluated without any use of booleans at all - it is all done with integers.
To achieve what you intended you need:
if((100 <= x) && (x <= 149))
etc. - which also doesn't use any booleans (&& is defined in terms of integers).