~~(“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参数转换为数字,但由于溢出的可能性,这是不正确的使用非整数,我不会用这种方式除了“代码高尔夫”( 即毫无意义地修剪程序源代码的字节,代价是可读性和鲁棒性)。 我会用+x
或Number(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