Estaba revisando una biblioteca de física de juegos en línea hoy y me encontré con el operador ~~. Sé que un solo ~ es un NO bit a bit, ¿eso haría que ~~ sea un NOT de un NOT, lo que devolvería el mismo valor, ¿no?
Estaba revisando una biblioteca de física de juegos en línea hoy y me encontré con el operador ~~. Sé que un solo ~ es un NO bit a bit, ¿eso haría que ~~ sea un NOT de un NOT, lo que devolvería el mismo valor, ¿no?
Respuestas:
Elimina todo después del punto decimal porque los operadores bit a bit convierten implícitamente sus operandos en enteros de 32 bits con signo. Esto funciona si los operandos son números o cadenas (de punto flotante) y el resultado es un número.
En otras palabras, produce:
function(x) {
if(x < 0) return Math.ceil(x);
else return Math.floor(x);
}
solo si x está entre - (2 31 ) y 2 31 - 1. De lo contrario, se producirá un desbordamiento y el número se "envolverá".
Esto puede considerarse útil para convertir el argumento de cadena de una función en un número, pero tanto por la posibilidad de desbordamiento como por el hecho de que es incorrecto para usar con números no enteros, no lo usaría de esa manera, excepto para "golf de código" ( es decir recortar bytes sin sentido del código fuente de su programa a expensas de la legibilidad y robustez). Yo usaría +xo en su Number(x)lugar.
El número -43.2, por ejemplo es:
-43.2 10 = 11111111111111111111111111010101 2
como un número binario de 32 bits con signo (complemento de dos). (JavaScript ignora lo que está después del punto decimal.) Invertir los bits da:
NO -43 10 = 00000000000000000000000000101010 2 = 42 10
Invertir nuevamente da:
NO 42 10 = 11111111111111111111111111010101 2 = -43 10
Esto difiere de Math.floor(-43.2)que los números negativos se redondean hacia cero, no lejos de él. (La función de piso, que sería igual a -44, siempre se redondea al siguiente entero más bajo, independientemente de si el número es positivo o negativo).
~~es una forma abreviada (y posiblemente una buena solución) para crear una función truncada , pero obviamente en JavaScript .
~~.
El primer operador ~ fuerza el operando a un número entero (posiblemente después de forzar el valor a una cadena o un booleano), luego invierte los 31 bits más bajos. Oficialmente, los números de ECMAScript son todos de punto flotante, pero algunos números se implementan como enteros de 31 bits en el motor SpiderMonkey.
Puede usarlo para convertir una matriz de 1 elemento en un entero. Los puntos flotantes se convierten de acuerdo con la regla C, es decir. truncamiento de la parte fraccional.
El segundo operador ~ luego invierte los bits, para que sepa que tendrá un número entero. Esto no es lo mismo que coaccionar un valor a booleano en una declaración de condición, porque un objeto vacío {} se evalúa como verdadero, mientras que ~~ {} se evalúa como falso.
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
~~undefined // 0
~~null // 0
~hace lo que usted describió ~, y viceversa. El ~operador es un operador unario y está interperado de derecha a izquierda ~~Xes como ~(~X)no (~~)X(lo que sería un error de sintaxis)
En ECMAScript 6, el equivalente de ~~es Math.trunc :
Devuelve la parte integral de un número eliminando los dígitos fraccionarios. No redondea ningún número.
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
El polyfill:
function trunc(x) {
return x < 0 ? Math.ceil(x) : Math.floor(x);
}
El ~parece hacer -(N+1). Entonces, ~2 == -(2 + 1) == -3si lo vuelve a hacer en -3, lo devuelve: ~-3 == -(-3 + 1) == 2probablemente solo convierte una cadena en un número de forma redondeada.
Vea este hilo: http://www.sitepoint.com/forums/showthread.php?t=663275
Además, hay información más detallada disponible aquí: http://dreaminginjavascript.wordpress.com/2008/07/04/28/
Dado ~Nes -(N+1), ~~Nes entonces -(-(N+1) + 1). Lo que, evidentemente, lleva a un buen truco .
Solo un poco de advertencia. Las otras respuestas aquí me metieron en problemas.
La intención es eliminar cualquier cosa después del punto decimal de un número de coma flotante, pero tiene algunos casos de esquina que lo convierten en un peligro de error. Recomiendo evitar ~~.
Primero, ~~ no funciona en números muy grandes.
~~1000000000000 == -727279968
Como alternativa, use Math.trunc()(como mencionó Gajus, Math.trunc()devuelve la parte entera de un número de coma flotante pero solo está disponible en JavaScript compatible con ECMAScript 6). Siempre puede hacer lo suyo Math.trunc()para entornos que no sean ECMAScript-6 haciendo esto:
if(!Math.trunc){
Math.trunc = function(value){
return Math.sign(value) * Math.floor(Math.abs(value));
}
}
Escribí una publicación de blog sobre esto para referencia: http://bitlords.blogspot.com/2016/08/the-double-tilde-x-technique-in.html
Aquí hay un ejemplo de cómo este operador se puede usar de manera eficiente, donde tiene sentido usarlo:
leftOffset = -(~~$('html').css('padding-left').replace('px', '') + ~~$('body').css('margin-left').replace('px', '')),
Fuente:
Convertir cadenas a números
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 es 0
if (~someStr.indexOf("a")) {
// Found it
} else {
// Not Found
}
Tilde (~) tiene un algoritmo - (N + 1)
Por ejemplo:
~0 = -(0+1) = -1
~5 = -(5+1) = -6
~-7 = -(-7+1) = 6
La tilde doble es - (- (N + 1) +1)
Por ejemplo:
~~5 = -(-(5+1)+1) = 5
~~-3 = -(-(-3+1)+1) = -3
La tilde triple es - (- (- (N + 1) +1) +1)
Por ejemplo:
~~~2 = -(-(-(2+1)+1)+1) = -3
~~~3 = -(-(-(3+1)+1)+1) = -4