search

Home  >  Q&A  >  body text

javascript - js 中的 ~~ 这种语法来自哪里,使用的时候跟Math.floor() 效果是一样的


// var sec = ~~ ( new Date().getTime() );
// 抱歉之前给的例子不太恰当,应该是如下的例子
var sec = ~~ ( ( end_time - new Date().getTime() ) ) / 1000 );

伊谢尔伦伊谢尔伦2817 days ago558

reply all(6)I'll reply

  • 怪我咯

    怪我咯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 位整数了,所以转换出来值是不正确的。

    reply
    0
  • 迷茫

    迷茫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
    

    reply
    0
  • 大家讲道理

    大家讲道理2017-04-10 15:00:52

    符号类型转换

    reply
    0
  • 巴扎黑

    巴扎黑2017-04-10 15:00:52

    RTFM

    http://php.net/manual/en/language.operators.bitwise.php

    reply
    0
  • 巴扎黑

    巴扎黑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的浮点数,向下取整。

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 15:00:52

    最近在看阮兄的 《Javascript标准参考教程》的运算符 一章时, 看到了关于这个问题的解释,自己再搬过来回答一下.

    否运算计算时将算子转成32位整数再运算, 即:
    ~3.1 === ~3
    ~ -4.1 === ~ -4

    另外, 整数两次否运算与与算子是相等的, 即:
    ~~ 3 === 3
    ~~ -3 === -3

    所以, 结合这两点的逻辑, 就可以达到取整的目的

    以上

    reply
    0
  • Cancelreply