Que fait ~ ~ ~ ("double tilde") dans Javascript?

j'étais en train de vérifier une bibliothèque de physique de jeu en ligne aujourd'hui et je suis tombé sur l'opérateur~~. Je sais une seule ~ est un not au niveau du bit, que cela ferait ~~ un PAS d'un PAS, ce qui donnerait la même valeur, ne serait-il pas?

175
demandé sur Jon Schneider 2010-10-30 00:27:52

9 réponses

il supprime tout après le point décimal parce que les opérateurs bitwise convertissent implicitement leurs opérandes en entiers signés 32 bits. Cela fonctionne que les opérandes soient des nombres (à virgule flottante) ou des chaînes, et le résultat est un nombre.

en d'autres termes, il donne:

function(x) {
  if(x < 0) return Math.ceil(x);
  else return Math.floor(x);
}

seulement si x se situe entre -(2 31 ) et 2 31 - 1. Sinon, dépassement de sera se produisent et le nombre "s'enroule autour".

cela peut être considéré comme utile pour convertir l'argument de chaîne d'une fonction à un nombre, mais à la fois en raison de la possibilité de débordement et qu'il est incorrect pour l'utilisation avec des non-entiers, Je ne l'utiliserais pas de cette façon sauf pour" golf de code "( c.-à-d. réduire inutilement les octets hors du code source de votre programme au détriment de la lisibilité et de la robustesse). J'utiliserais +x ou Number(x) à la place.


Comment c'est le PAS de la ne PAS

le nombre -43.2, par exemple est:

-43.2 10 = 11111111111111111111111111010101 2

comme un nombre binaire 32 bits signé (complément de deux). (JavaScript ignore ce qui est après le point décimal.) Inversant les bits donne:

NOT -43 10 = 00000000000000000000000000101010 2 = 42 10

inversant à nouveau donne:

NOT 42 10 = 11111111111111111111111111010101 2 = -43 10

cela diffère de Math.floor(-43.2) en ce que les nombres négatifs sont arrondis vers zéro, et non loin de celui-ci. (La fonction de plancher, qui serait égale -44, tourne toujours vers le bas à l'entier inférieur suivant, indépendamment du fait que le nombre est positif ou négatif.)

219
répondu PleaseStand 2012-03-31 21:56:56

le premier opérateur ~ Force l'opérande à un entier (peut-être après avoir forcé la valeur à une chaîne ou à un booléen), puis inverse les 31 bits les plus bas. Officiellement, les nombres ECMAScript sont tous à virgule flottante, mais certains nombres sont implémentés comme des entiers de 31 bits dans le moteur SpiderMonkey.

vous pouvez l'utiliser pour transformer un tableau 1-element en un entier. Les points flottants sont convertis selon la règle C, c.-à-d. la troncature de la partie fractionnaire.

le second opérateur ~ inverse alors les bits en arrière, de sorte que vous savez que vous aurez un entier. Ce n'est pas la même chose que de forcer une valeur à booléen dans une instruction de condition, parce qu'un objet vide {} évalue à true, alors que ~ {} évalue à false.

js>~~"yes"
0
js>~~3
3
js>~~"yes"
0
js>~~false
0
js>~~""
0
js>~~true
1
js>~~"3"
3
js>~~{}
0
js>~~{a:2}
0
js>~~[2]
2
js>~~[2,3]
0
js>~~{toString: function() {return 4}}
4
js>~~NaN
0
js>~~[4.5]
4
js>~~5.6
5
js>~~-5.6
-5
29
répondu Shanti 2010-10-29 23:52:42

en ECMAScript 6, l'équivalent de ~~ est en mathématiques.trunc :

renvoie la partie intégrante d'un nombre en supprimant tout chiffre fractionnaire. Il ne arrondit aucun chiffre.

Math.trunc(13.37)   // 13
Math.trunc(42.84)   // 42
Math.trunc(0.123)   //  0
Math.trunc(-0.123)  // -0
Math.trunc("-1.123")// -1
Math.trunc(NaN)     // NaN
Math.trunc("foo")   // NaN
Math.trunc()        // NaN

Le polyfill:

function trunc(x) {
    return x < 0 ? Math.ceil(x) : Math.floor(x);
}
14
répondu Gajus 2014-12-17 15:10:50

Le ~ semble faire -(N+1) . Donc ~2 == -(2 + 1) == -3 si vous le faites à nouveau sur -3 il le retourne: ~-3 == -(-3 + 1) == 2 il convertit probablement juste une chaîne à un nombre d'une manière ronde.

voir ce fil: http://www.sitepoint.com/forums/showthread.php?t=663275

aussi, des informations plus détaillées sont disponibles ici: http://dreaminginjavascript.wordpress.com/2008/07/04/28 /

12
répondu Richard Marskell - Drackir 2010-10-29 20:35:31

donné ~N est -(N+1) , ~~N est alors -(-(N+1) + 1) . Ce qui, évidemment, conduit à un astuce soignée .

8
répondu James Sumners 2010-10-29 20:38:29

juste un petit avertissement. Les autres réponses m'ont attiré des ennuis.

l'intention est de supprimer n'importe quoi après le point décimal d'un nombre de virgule flottante, mais il a quelques cas de coin qui en font un risque de bogue. Je recommande d'éviter les ~~.

tout d'Abord, ~~ ne fonctionne pas sur de très grands nombres.

~~1000000000000 == -727279968

comme alternative, utilisez Math.trunc() (comme Gajus l'a mentionné, Math.trunc() renvoie la partie entière d'un nombre flottant, mais N'est disponible qu'en JavaScript compatible avec ECMAScript 6). Vous pouvez toujours faire votre propre Math.trunc() pour les environnements non-ECMAScript-6 en faisant ceci:

if(!Math.trunc){
    Math.trunc = function(value){
        return Math.sign(value) * Math.floor(Math.abs(value));
    }
}

j'ai écrit un billet de blog sur ce sujet pour référence: http://bitlords.blogspot.com/2016/08/the-double-tilde-x-technique-in.html

2
répondu JSideris 2017-06-09 02:07:00

Voici un exemple de la façon dont cet opérateur peut être utilisé efficacement, où il est logique de l'utiliser:

leftOffset = -(~~$('html').css('padding-left').replace('px', '') + ~~$('body').css('margin-left').replace('px', '')),

Source:

voir la section en interaction avec les points

1
répondu gibberish 2015-07-19 14:32:12

convertir des chaînes de caractères en nombres

console.log(~~-1);    // -1
console.log(~~0);     // 0
console.log(~~1);     // 1
console.log(~~"-1");  // -1
console.log(~~"0");   // 0
console.log(~~"1");   // 1
console.log(~~true);  // 1
console.log(~~false); // 0

~-1 0

if (~someStr.indexOf("a")) {
  // Found it
} else  {
  // Not Found
}

source

1
répondu Mykhaylo Adamovych 2016-12-26 12:38:13

Tilde (~) a un algorithme -(N+1)

par exemple:

~0 = -(0+1) = -1
~5 = -(5+1) = -6
~-7 = -(-7+1) = 6

Double tilde est -(-(N+1)+1)

par exemple:

~~5 = -(-(5+1)+1) = 5
~~-3 = -(-(-3+1)+1) = -3

Triple tilde est -(-(-(N+1)+1)+1)

par exemple:

~~~2 = -(-(-(2+1)+1)+1) = -3
~~~3 = -(-(-(3+1)+1)+1) = -4
0
répondu CroMagnon 2017-09-23 01:12:00