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