Skip to main content

What does ~~ do in Javascript?



I was checking out an online game physics library today and came across the ~~ operator. I know a single ~ is a bitwise NOT, would that make ~~ a NOT of a NOT, which would give back the same value, wouldn't it?





Thanks, Shane



Source: Tips4all

Comments

  1. It removes everything after the decimal point because the bitwise operators implicitly convert their operands to signed 32-bit integers. This works whether the operands are (floating-point) numbers or strings, and the result is a number.

    In other words, it yields:

    function(x) {
    if(x < 0) return Math.ceil(x);
    else return Math.floor(x);
    }


    only if x is between -(231) and 231 - 1. Otherwise, overflow will occur and the number will "wrap around".

    This may be considered useful to convert a function's string argument to a number, but both because of the possibility of overflow and that it is incorrect for use with non-integers, I would not use it that way except for "code golf" (i.e. pointlessly trimming bytes off the source code of your program at the expense of readability and robustness). I would use +x or Number(x) instead.



    How this is the NOT of the NOT

    The number -43.2, for example is:

    -43.210 = 111111111111111111111111110101012

    as a signed (two's complement) 32-bit binary number. (JavaScript ignores what is after the decimal point.) Inverting the bits gives:

    NOT -4310 = 000000000000000000000000001010102 = 4210

    Inverting again gives:

    NOT 4210 = 111111111111111111111111110101012 = -4310

    This differs from Math.floor(-43.2) in that negative numbers are rounded toward zero, not away from it. (The floor function, which would equal -44, always rounds down to the next lower integer, regardless of whether the number is positive or negative.)

    ReplyDelete
  2. The ~ seems to do -(N+1). So ~2 == -(2 + 1) == -3 If you do it again on -3 it turns it back: ~-3 == -(-3 + 1) == 2 It probably just converts a string to a number in a round-about way.

    See this thread: http://www.sitepoint.com/forums/showthread.php?t=663275

    Also, more detailed info is available here: http://dreaminginjavascript.wordpress.com/2008/07/04/28/

    ReplyDelete
  3. Given ~N is -(N+1), ~~N is then -(-(N+1) + 1). Which, evidently, leads to a neat trick.

    ReplyDelete
  4. The first ~ operator forces the operand to an integer (possibly after coercing the value to a string or a boolean), then inverts the lowest 31 bits. Officially ECMAScript numbers are all floating-point, but some numbers are implemented as 31-bit integers in the SpiderMonkey engine.

    You can use it to turn a 1-element array into an integer. Floating-points are converted according to the C rule, ie. truncation of the fractional part.

    The second ~ operator then inverts the bits back, so you know that you will have an integer. This is not the same as coercing a value to boolean in a condition statement, because an empty object {} evaluates to true, whereas ~~{} evaluates to 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

    ReplyDelete

Post a Comment

Popular posts from this blog

Slow Android emulator

I have a 2.67 GHz Celeron processor, 1.21 GB of RAM on a x86 Windows XP Professional machine. My understanding is that the Android emulator should start fairly quickly on such a machine, but for me it does not. I have followed all instructions in setting up the IDE, SDKs, JDKs and such and have had some success in staring the emulator quickly but is very particulary. How can I, if possible, fix this problem?