Pourquoi (0 <5 <3) est-il vrai?

Je jouais dans jsfiddle.net et je suis curieux de savoir pourquoi cela revient vrai?

if(0 < 5 < 3) { alert("True"); } 

De même:

 if(0 < 5 < 2) { alert("True"); } 

Mais ce n'est pas le cas:

 if(0 < 5 < 1) { alert("True"); } 

Est-ce que cette capuche est toujours utile?

L'ordre des opérations entraîne (0 < 5 < 3) à être interprété en javascript car ((0 < 5) < 3) qui produit (true < 3) et vrai est compté comme 1, ce qui lui permet de revenir vrai.

C'est aussi pourquoi (0 < 5 < 1) renvoie false, (0 < 5) renvoie true, qui est interprété comme 1 , ce qui donne (1 < 1) .

Je suppose que 0 < 5 est vrai, et le true < 3 est transmis à 1 < 3 ce qui est vrai.

Probablement parce que true est supposé

 0 < 5 < 3 --> true < 3 --> 1 < 3 --> true 

Parce que true < 3 , parce que true == 1

En ce qui concerne votre question de savoir si ce quirk est toujours utile: je suppose qu'il pourrait y avoir un cas où il serait utile (si le code condensé est ce que vous recherchez), mais en s'appuyant (probablement) réduira considérablement la compréhension de votre code.

C'est un peu comme utiliser post / pré-incrément / décrément dans le cadre d'expressions plus importantes. Pouvez-vous déterminer quel résultat de ce code est en un coup d'œil?

 int x = 5; int result = ++x + x++ + --x; 

Remarque: avec ce code, vous pouvez parfois même obtenir des résultats différents en fonction de la langue et du compilateur.

C'est une bonne idée de rendre la vie facile pour vous-même et le prochain qui va lire votre code. Écrivez clairement ce que vous voulez réellement avoir lieu plutôt que de compter sur des effets secondaires comme la conversion implicite de booléens.

La réponse à la deuxième partie de la question, "est-ce que cette capuche est toujours utile?" Est peut-être non, comme l'a noté une réponse précédente, si c'est en effet un caprice de la langue (Javascript) que vraie est transmise à 1, mais que le programmeur ne regarde pas en général 1 et vrai (et 0 et faux) comme le même chose.

Si toutefois vous avez un modèle mental de 1 étant vrai et 0 étant faux, cela conduit à toutes sortes de belles techniques booléennes extrêmement utiles, puissantes et directes. Par exemple, vous pouvez incrémenter un compteur directement avec le résultat de A> 100, ce qui augmenterait le compteur si A est supérieur à 100. Cette technique pourrait être considérée comme un caprice ou un tour en Java, mais dans un tableau ou un langage fonctionnel Peut être idiomatique.

Un exemple classique dans la langue de tableau APL serait de compter le nombre d'éléments dans un tableau qui est (par exemple) supérieur à 100:

 +/A>100 

Où si A est le tableau de 5 éléments 107 22 256 110 3 alors:

 A>100 

Donne le tableau booléen 5 items:

1 0 1 1 0

Et la somme de ce résultat booléen:

 +/1 0 1 1 0 

Donne la réponse finale:

3

Cette question est un exemple parfait d'où cette technique serait très utile, surtout si le problème est généralisé pour déterminer si n hors de m valeurs booléennes sont vraies.

Vérifiez si au moins deux des trois booleans sont vrais

C'est facile.

 (0 < 5 < 3) 

Commencez de gauche à droite afin d'évaluer le premier 0 <5. Est-ce vrai? Oui. Comme TRUE = 1, il évalue 1 <3. Puisque 1 est inférieur à 3, il est vrai.

Maintenant avec cela

  (0 < 5 < 1) 

Est-ce que 0 est inférieur à 5? Oui. Donc, faites-le TRUE ce qui signifie également 1. Maintenant, en tenant compte de cela, il évalue (1 <1). Est-ce que 1 est inférieur à 1? Non, donc c'est faux. Cela doit être égal.

Est-ce qu'il évalue 0 <5 qui renverra 1 pour vrai quand 1 <3 qui est vrai?

C # voulez vous permettre de faire ceci "L'opérateur '<' ne peut pas être appliqué aux opérandes de type 'bool' et 'int'"

J'ai rencontré cela il y a un moment dans Obj-C et j'étais très perplexe. J'ai obtenu les résultats que je voulais en faisant quelque chose comme ça:

 if(0 < 5 && 5 < 3) { alert("True");} 

Ce qui, bien sûr, est faux, donc vous n'obtiendrez pas cette «vraie» alerte. Content de lire cela, je sais maintenant pourquoi.

En plus de python, CoffeeScript est une autre langue qui prend en charge les comparaisons enchaînées, donc 3 < x < 10 seraient convertis en (3 < x && x < 10) dans vanilla JS

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

Un opérande booléen lorsqu'il est opéré sur un opérateur mathématique renvoie un nombre. Pour vérifier cela, nous faisons

 true + 1 which gives you 2. 

Ainsi, 0 < 5 , le booléen renvoyé (vrai) opéré avec un opérateur mathématique (<) renverra un nombre. Donc, cela se résume à 1 <3 qui renvoie true