// var sec = ~~ ( new Date().getTime() );
// 抱歉之前给的例子不太恰当,应该是如下的例子
var sec = ~~ ( ( end_time - new Date().getTime() ) ) / 1000 );
怪我咯2017-04-10 15:00:52
首先解释下为什么 ~~ 可以达到 Math.floor() 类似的效果:
关于 ~
(位取反),我们可以从 ECMAScript 了解到它的算法,注意到第二步,再进行位取反前,需要先将数值进行 ToInt32 运算,而在 ToInt32 里,有一个 sign(number) * floor(abs(number))
——这是取整的操作。
因此用 ~~
来取整,实际是用 ToInt32 时的取整操作,类似的其他操作(如 num >> 0
)也一样。
但这些操作也有一个很大的问题,就是当需要取整的数超过 32 位里,操作会得到一个错误的值,因为在 ToInt32 里除了取整操作,还把 数值 % 2<sup>32</sup>
(转成 32 位数值)。
如 ~~17179869222.23042 == 38(正确取整后的值应该是 17179869222)
从题主给出的代码:var sec = ~~ ( new Date().getTime() );
,有两个问题,一是 .getTime() 就已经是整数了,不需要转了;二是 .getTime() 的值已经超过 32 位整数了,所以转换出来值是不正确的。
迷茫2017-04-10 15:00:52
跟Math.floor()
还是不一样的 ,实际上等效于
function trunc(x) {
return x < 0 ? Math.ceil(x) : Math.floor(x);
}
~
做的操作是按位取反,两次取反又会变回原操作数
但是当操作数是小数的时候,会忽略其小数部分
~~43.2 == ~(~43.2) == ~(~43) == ~ ~43 == (~ ~)43 == 43
~~-43.2 == ~(~-43.2) == ~(~-43) == ~ ~-43 == (~ ~)-43 == -43
Math.floor(-43.2) == -44
巴扎黑2017-04-10 15:00:52
~按位非运算符,位于整型参数之前,它将所有操作位取反。相当于改变运算数的符号并减去1。
由于操作数不一定是整数,所以要进行数据类型转换。
~可以简单理解为下面的表达式:
var oper = ~2;
var oper = (-fn(2)) - 1;
function fn(num) {
return isNaN(parseInt(num, 10)) ? -1 : parseInt(num, 10);
}
~~:
var oper = ~~2;
var oper = fn(2);
function fn(num) {
return isNaN(parseInt(num, 10)) ? -1 : parseInt(num, 10);
parseInt在做类型转换的时候会根据操作数向下或者向上取整。
操作数是小于0的浮点数,向上取整。
操作数是大于0的浮点数,向下取整。
PHP中文网2017-04-10 15:00:52
最近在看阮兄的 《Javascript标准参考教程》的运算符 一章时, 看到了关于这个问题的解释,自己再搬过来回答一下.
否运算计算时将算子转成32位整数再运算, 即:
~3.1 === ~3
~ -4.1 === ~ -4
另外, 整数两次否运算与与算子是相等的, 即:
~~ 3 === 3
~~ -3 === -3
所以, 结合这两点的逻辑, 就可以达到取整的目的
以上