【问题标题】:How does ~~ work as math.floor? [duplicate]~~ 如何作为 math.floor 工作? [复制]
【发布时间】:2014-04-12 04:46:25
【问题描述】:

我知道 ~ 是一个按位 NOT 运算符,但是如何将数字上的位反转两次使其像 Math.floor What does ~~ ("double tilde") do in Javascript? 描述了在 Javascript 中使用 Math.floor 与按位运算来舍入数字之间的区别,但我感兴趣的是如何准确地将位反转两次来实现这一点。

谢谢

【问题讨论】:

    标签: javascript double


    【解决方案1】:

    ~ 强制将操作数强制转换为整数。解决 Javascript 无法在浮点值和整数值之间进行直接转换的事实是一个技巧。事实上,Javascript 并没有正式的仅整数类型,但实现很可能在内部使用整数来提高性能。

    所以~xcastToInt(x) 的按位倒数。然后你再次反转位得到castToInt(x)

    恰好将浮点数转换为整数的行为几乎类似于Math.floor。最显着的区别是,将四舍五入向零,而Math.floor 向负无穷大舍入。还有一些其他的区别:

    js> ~~(-4.5)
    -4
    js> Math.floor(-4.5)
    -5
    js> ~~Infinity
    0
    js> Math.floor(Infinity)
    Infinity
    js> ~~NaN
    0
    js> Math.floor(NaN)
    NaN
    js> Math.floor(1e12)
    1000000000000
    js> ~~1e12 
    -727379968      // <- be aware of integer overflows!
    

    【讨论】:

      【解决方案2】:

      它本质上相当于截断函数(从某种意义上说,它将浮点数转换为整数,正是这样做的),这是 JavaScript 所没有的。这就是为什么负数的行为实际上更接近于Math.ceil

      【讨论】:

        【解决方案3】:

        来自the spec,按位非,~

        1. expr 成为评估UnaryExpression的结果。
        2. oldValue 成为ToInt32(GetValue(expr))
        3. 将按位补码的结果返回到oldValue。结果是一个带符号的 32 位整数。

        ToInt32here 的定义。

        32 位整数i 的“补码”是i XOR 0xFFFFFFFF

        所以把这一切放在一起,你就有了~~i 的含义

        ToInt32(i) XOR 0xFFFFFFFF XOR 0xFFFFFFFF
        // same as 
        ToInt32(i) XOR 0x00000000
        // same as
        ToInt32(i) 
        

        请记住负数舍入方向的差异。


        我个人更喜欢使用x | 0 而不是~~x,因为它涉及更少的操作以获得相同的结果。

        【讨论】:

        • 我刚刚失去了 1 个小时,直到我意识到 ~~ 只截断小数,所以它在负数上的行为不像 Math.floor()。另外,我读到 Math.floor() 现在具有几乎相同的性能,所以使用 ~~ 真的没有意义。
        猜你喜欢
        • 1970-01-01
        • 2018-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-21
        • 2012-06-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多