~~(“double tilde”)在Javascript中做什么?

我今天正在查看一个在线游戏物理库,并遇到了~~运算符。 我知道一个单独的〜是不是一个按位不是,会不会让一个NOT不是一个NOT,这会给出相同的值,不是吗?

它将删除小数点后的所有内容,因为按位运算符会将其操作数隐式转换为带符号的32位整数。 无论操作数是(浮点)数字还是string,结果都是一个数字。

换句话说,它会产生:

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

只有当x介于 – (2 31 )和2 31 – 1之间时。否则,将发生溢出并且数字将“回绕”。

这可能被认为是有用的函数的string参数转换为数字,但由于溢出的可能性,这是不正确的使用非整数,我不会用这种方式除了“代码高尔夫”( 毫无意义地修剪程序源代码的字节,代价是可读性和鲁棒性)。 我会用+xNumber(x)来代替。


这是不是NOT的

数字-43.2,例如是:

-43.2 10 = 11111111111111111111111111010101 2

作为一个有符号(二进制补码)的32位二进制数。 (JavaScript会忽略小数点后的内容。)反转这些位给出:

NOT -43 10 = 000000000000000000000000101010 2 = 42 10

再次倒转给出:

NOT 42 10 = 11111111111111111111111111010101 2 = -43 10

这与Math.floor(-43.2)不同之处在于,负数被舍入为零,而不是离开它。 (底线函数,等于-44,总是舍入到下一个较低的整数,而不pipe数字是正数还是负数。)

第一个〜操作符强​​制操作数为一个整数(可能在将值强制为string或布尔值之后),然后反转最低的31位。 正式的ECMAScript数字都是浮点数,但有些数字在SpiderMonkey引擎中以31位整数实现。

您可以使用它将1个元素的数组转换为一个整数。 根据C规则转换浮点,即。 截断小数部分。

第二个操作符然后将这些位反转,所以你知道你将有一个整数。 这与在条件语句中将值强制为布尔值不同,因为空对象的计算结果为true,而计算结果为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 

~似乎是-(N+1) 。 所以~2 == -(2 + 1) == -3如果在-3上再次执行它,它会将其变回: ~-3 == -(-3 + 1) == 2它可能只是将string转换为一个数字在一个圆的方式。

看到这个线程: http : //www.sitepoint.com/forums/showthread.php? t= 663275

此外,更详细的信息可在这里: http : //dreaminginjavascript.wordpress.com/2008/07/04/28/

在ECMAScript 6中,相当于~~是Math.trunc :

通过删除小数位来返回数字的整数部分。 它不包括任何数字。

 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 

polyfill:

 function trunc(x) { return x < 0 ? Math.ceil(x) : Math.floor(x); } 

如果~N-(N+1) ,则~~N-(-(N+1) + 1) 。 显然,这导致了一个巧妙的把戏 。

这里是一个如何有效使用这个操作符的例子,在哪里使用它是有意义的:

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

资源:

请参阅与点交互部分

将string转换为数字

 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 } 

资源

只是一点警告。 这里的其他答案让我陷入了一些麻烦。

意图是在浮点数的小数点后面删除任何东西,但是它有一些使得它成为bug的危险。 我build议避免~~。

首先,~~不适用于非常大的数字。

~~1000000000000 == -727279968

作为替代,使用Math.trunc() (如Gajus提到的, Math.trunc()返回浮点数的整数部分,但仅在符合ECMAScript 6的JavaScript中可用)。 对于非ECMAScript-6环境,您可以始终创build自己的Math.trunc() ,方法如下:

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

Tilde(〜)有一个algorithm – (N + 1)

例如:

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

双重代字符是 – ( – (N + 1)+1)

例如:

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

三重代字符是 – ( – ( – (N + 1)+1)+1)

例如:

 ~~~2 = -(-(-(2+1)+1)+1) = -3 ~~~3 = -(-(-(3+1)+1)+1) = -4