Why does (0 < 5 < 3) return true? - javascript

I was playing around in jsfiddle.net and I'm curious as to why this returns true?
if(0 < 5 < 3) {
alert("True");
}
So does this:
if(0 < 5 < 2) {
alert("True");
}
But this doesn't:
if(0 < 5 < 1) {
alert("True");
}
Is this quirk ever useful?

Order of operations causes (0 < 5 < 3) to be interpreted in javascript as ((0 < 5) < 3) which produces (true < 3) and true is counted as 1, causing it to return true.
This is also why (0 < 5 < 1) returns false, (0 < 5) returns true, which is interpreted as 1, resulting in (1 < 1).

My guess is because 0 < 5 is true, and true < 3 gets cast to 1 < 3 which is true.

probably because true is assumed as 1 so
0 < 5 < 3 --> true < 3 --> 1 < 3 --> true

Because true < 3, because true == 1

As to your question whether this quirk is ever useful: I suppose there could be some case where it would useful (if condensed code is what you are after), but relying on it will (most likely) severely reduce the understandability of your code.
It's kind of like using post/pre increment/decrement as a part of bigger expressions. Can you determine what this code's result is at a glance?
int x = 5;
int result = ++x + x++ + --x;
Note: with this code, you can sometimes even get different results depending on the language and compiler.
It's a good idea to make life easy for yourself and the next guy who will read your code. Clearly write out what you actually want to have happen rather then relying on side effects like the implicit conversion of booleans.

The answer to the second part of the question, "is this quirk ever useful?" is perhaps no, as noted by a previous answer, if it is indeed a quirk of the language (Javascript) that true is cast to 1, but that the programmer does not in general view 1 and true (and 0 and false) as the same thing.
If however you have a mental model of 1 being true and 0 being false, then it leads to all sorts of nice boolean techniques that are extremely useful, powerful, and direct. For example, you could increment a counter directly with the result of A > 100, which would increment the counter if A is greater than 100. This technique might be viewed as a quirk or a trick in Java, but in an array or functional language may be idiomatic.
A classic example in the array language APL would be to count the number of items in an array that are (say) greater than 100:
+/A>100
Where if A is the 5 item array 107 22 256 110 3 then:
A>100
yields the 5 item boolean array:
1 0 1 1 0
and summing this boolean result:
+/1 0 1 1 0
yields the final answer:
3
This question is a perfect example of where this technique would be very useful, especially if the problem is generalized to determine if n out of m boolean values are true.
Check if at least two out of three booleans are true

That's easy.
(0 < 5 < 3)
Start with left to right so it evaluates the first 0 < 5. Is it true? Yes. Since TRUE=1, it evaluates 1 < 3. Since 1 is less than 3 so it's true.
Now with this
(0 < 5 < 1)
Is 0 less than 5? Yes. So make it TRUE which also means 1. Now with that fact in mind, it evaluates to (1 < 1). Is 1 less than 1? No, therefore it's false. It has to be equal.

is it evaluating 0<5 which would return 1 for true when 1<3 which is true?
C# want let you do this "Operator '<' cannot be applied to operands of type 'bool' and 'int'"

I ran into this a little while ago in Obj-C and was very puzzled by it. I got the results I wanted by doing something like this:
if(0 < 5 && 5 < 3) {
alert("True");}
Which of course is false so you wouldn't get that "true" alert.
Glad I read this, I now know why.

In addition to python, CoffeeScript is another language that supports chained comparisons, thus 3 < x < 10 would be converted to (3 < x && x < 10) in vanilla JS

0 < 5 < 3
==> ( ( 0 < 5 ) < 3 )
==> true < 3
==> 1 < 3
==> true

A boolean operand when operated over a math operator returns a number.
to check this we do
true + 1 which gives you 2.
So 0 < 5, the returned boolean(true) operated with math operator(<) will return a number. So it boils to 1<3 which returns true

because 0 is less then 5 then that returns true, and by default true is anything including and can be evaluated to 1 which is still less than 3 which again returns true

try phrasing your results as Number()
if(Number(0) < Number(5) < Number(3)) {
alert("True");
}
or try this:
if(Number(0) < Number(5) && Number(5) < Number(3)) {
alert("True");
}
I googled this because I was getting (3 >= 20) //returning true and I guess javascript was trying to check 3 as a boolean because I was getting this value from the elm.getAttribute(); function which console.log(); was printing in String form.

Related

& 1 JavaScript. How does it work? Clever or good? [duplicate]

This question already has answers here:
Is there a & logical operator in Javascript
(8 answers)
Closed 6 years ago.
I'm looking over the solutions for a CodeWars problem (IQ Test) in which you're given a string of numbers and all the numbers but 1 are either even or odd. You need to return the index plus 1 of the position of the number that's not like the rest of the numbers.
I'm confused about the line that says & 1 in the solution posted below. The code doesn't work w/ && or w/ the & 1 taken away.
function iqTest(numbers){
numbers = numbers.split(' ')
var evens = []
var odds = []
for (var i = 0; i < numbers.length; i++) {
if (numbers[i] & 1) { //PLEASE EXPLAIN THIS LINE!
odds.push(i + 1)
} else {
evens.push(i + 1)
}
}
return evens.length === 1 ? evens[0] : odds[0]
}
Also, would you consider using & 1 to be best practice or is it just "clever" code?
The single & is a 'bitwise' operator. This specific operator (&) is the bitwise AND operator - which returns a one in each bit position for which the corresponding bits of both operands are ones.
The way it's being used here is to test if numbers[i] is an even or odd number. As i loops from 0 to numbers.length, for the first iteration the if statement evaluates 0 & 1 which evaluates to 0, or false. On the next iteration of the loop, the statement will be 1 & 1, which evaluates to 1, or true.
The result - when numbers[i] & 1 evaluates to 0, or false, then numbers[i] is pushed to the odd array. If numbers[i] & 1 evaluates to 1, or true, then numbers[i] is pushed to the even array.
An alternative to the & operator to test for even and odd is to use the modulo operator. numbers[i] % 2 results in the same output. That is, 1 % 2 results in 1, or true as will any odd number, because an odd number divided by 2 results in a remainder of 1. And any even number, like 2 % 2 results in 0 or false because an even number divided by 2 results in a remainder of 0.
As for your second question, is it 'clever or good?'. It's definitely clever. Whether it's good depends on who you ask and what your goal is. Many would say its less logical and harder to read than using num % 2.
Binary number is 0 and 1 and each of them is called bit.
Single & is add operation and it works bitwise.
like
1 = 01
2 = 10
3 = 11
4 = 100
You can see that every last bit of odd number is 1 and even number is 0.
In add operation
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
So only odd number will return 1 and even number will return 0 and in programming only 0 consider falsy.
If we wanna to check 5 is a odd or even
5 = 101
and perform and(&) operation with 1
101
& 001
-----
001
and value of binary 001 is 1 in 10 base number
So it'll perform easy odd even process.

(!n%2) is the same as (!n%2 == 0)?

I am trying to understand this code from Eloquent JavaScript:
function unless(test, then) {
if (!test) then();
}
function repeat(times, body) {
for (var i = 0; i < times; i++) body(i);
}
repeat(3, function(n) {
unless(n % 2, function() {
console.log(n, "is even");
});
});
// → 0 is even
// → 2 is even
I get that it says, run the following code 3 times testing with 0,1,2:
if (!n%2) function(n) {
console.log(n, "is even");
});
What I don't get is how we get true/false from (!n%2)?
Is (!n%2) the same as (!n%2 == 0)?
Logical NOT ! has higher precedence than modulo operator %.
Thus, (!n%2) is equivalent to (!n) % 2 which will always return 0 a falsy value except when n = 0.
Whereas (!n%2 == 0) will return true(again except 0).
They both are not equal, in fact they are opposite of each other(falsy vs truthy value).
You need !(n % 2).
Or simply to check if number is even
n % 2 === 0
Your test code you wrote is not equivalent to the sample code from the article.
In the sample code, n % 2 is evaluated first, and the result is passed into the unless function. There, you are performing a Logical Not operation against the result.
If n is even, n % 2 will pass 0 to unless. A Boolean comparison of 0 returns false, and the ! negates the result (logical not), so !0 == true. this, in turn, causes the then function to fire.
If n is odd, the opposite occurs. Some value other than 0 is passed, which evaluates to false, causing then to not fire.
In contrast, your attempt to reproduce the sample code without using Higher-Order functions won't work the same way. !n % 2 will perform the Logical Not on n first, then try to modulo the result. !(n % 2) is a better representation of the sample code.
!Boolean(n%2) should work as a way to determine whether one is even or odd.
Remember that Boolean does not follow BIDMAS.
It does !n first where n is treated as a Boolean so that the numerical value of 0 is treated as false and any other numerical value is treated as true. The exclamation mark inverts the logic state of n.
Now the %2 converts the Boolean back to an integer where true is 1 and 0 is false. !n = 0 returns 0 and !n = 1 returns 1.
Using !n%2 in an if statement converts it back to a Boolean (1 = true, 0 = false).
Thus if n = 0 then the if statements proceeds because it returned true. If n != 0 (!= meaning not equal) then if statement is skipped because it returned false.
No, it's not. As stated here the "!" operator has highest precedence than "%" so the expression will return true if n is 0 and false if n is different from 0.
More in detail, suppose n is 2. the execution of the expression is:
(!n)%2
(!2)%2
0%2
0
so it is false, now for n=0
(!0)%2
1%2
1
so it is true. It is the opposite behavior of (!n%2 == 0) that returns true if n is different from 0 and false otherwise since == has less precendence and the comparison with 0 is executed at the end of the calculation above. You can easily convince yourself by using this simple javascript with different values of n:
n = 1;
if(!n%2)
{
document.getElementById("par1").innerHTML="true";
}
if(!n%2 == 0)
{
document.getElementById("par2").innerHTML="true";
}

Why does JavaScript return false when comparing a variable with two true statements?

In the following javascript code,
var a = 5;
console.log(5 <= a >= 6);
False is printed to the console.
However, true is printed for the statements 5 <= a and a >= 6. Is it something to do with the double comparisons?
Thanks!
When you test if 5 is less than or equal to 5 you get true
When you test if true is greater than or equal to 6 you get false
(You would also get false if you tested to see if 5 was greater than or equal to 6)
If you want to do multiple tests with the same value, then you need to actually test that value multiple times.
e.g.
if (5 <= 6 && 5 <= 6)
or
if (5 <= 6 || 5 >= 6)
When you write things like this, you seem to be testing whether:
(5 <= a) >= 6
"5 <= a" evaluates to true, but the statement "true >= 6" evaluates to false.

Javascript expression: double greater than x and greater than y

So I wondered to myself if there is a way to do a double greater than, like this:
if(x > y > z) { ... }
Then I saw this
Expression for "more than x and less than y"?
But then I tried the following expression in the console and got a weird result:
(5 < 2 < 1) // returned true
(5 > 2 > 1) // returned false
How?
Update: I know that you can't do this "(x > y > z)", just wanted explanation on the weird result.
You need two separate conditions, such as 5<2 && 2<1 for this to do what you're after. Without two conditions, you are comparing the result of the first condition against the right side of the second condition.
Why?
For the unexplained behaviour, I believe that the explanation for why it's returning what it's returning is the way javascript handles booleans (among other things) when used in numerical operations, in other words, javascript will cast your booleans to 0 or 1, there are a lot of examples of this in a few questions here at so, for example this one, you could do +false and get a 0 for instance.
(5 < 2 < 1) is true because:
5<2 is resolved first, returning false
false is cast to a number, returning 0
0<1 will return true
(5 > 2 > 1) is false because:
5>2 is resolved first, will return true
true is cast to a number, will return 1
1>1 will return false
No. You can't do this in JavaScript. Much as it would be useful, you're stuck with x > y && y > z.
That said, to explain your result:
5 < 2 gives false
false casts to 0
0 < 1 is true
And:
5 > 2 gives true
true casts to 1
1 > 1 is false
As far as a "way to do a double greater than", you could define a function:
function gt () {
var prev = arguments[0];
return !([].slice.call(arguments, 1).some(function (arg) {
var ret = prev <= arg;
prev = arg;
return ret;
}));
}
...then call like this:
if(gt(x, y, z)) { ... }
I would just try if((5>2) && (2>1)) {
} not sure why the other one didnt work but thus implementation should be a proper substitute for code that could be written in the other way you have it.

I am having some issues interpreting inequalities with Javascript Operators

For my little app I need to do some very simple math... But for some reason I am having trouble doing it with JavaScript.
Here is the code:
(elLeftY <= elementLeftY <= elRightY)
If one of the "questions" is false but the other one is true this little code will always output true... What I want is that only when the two "questions" are true then it equals true but if one of the two is false then it equals false.
Thanks allot in advance.
You can't do it like that in javascript. You need this instead:
(elLeftY <= elementLeftY) && (elementLeftY <= elRightY)
Here is how your current code is being evaluated:
(elLeftY <= elementLeftY <= elRightY)
((elLeftY <= elementLeftY) <= elRightY)
(true <= elRightY)
(1 <= elRightY)
true
You cannot cascade equality checks in Javascript, you have to split them into two expressions.
((elLeftY <= elementLeftY) && (elementLeftY <= elRightY))

Categories

Resources