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?
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.)
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
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);
}
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 /
donné ~N
est -(N+1)
, ~~N
est alors -(-(N+1) + 1)
. Ce qui, évidemment, conduit à un astuce soignée .
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
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:
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
}
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