Hello and welcome to our community! Is this your first visit?
Enjoy an ad free experience by logging in. Not a member yet? Register.

# Thread: >> syntax

1. ## >> syntax

So reading through a pluggin, I'm coming across this syntax:

Code:
`var x = (mx - sImg.offset().left) >> 0`
The math part I get fine, I'm more confused what the ">> 0" means, namely in terms of the assignment?

EDIT: I know >>/<< are used for bitwise operations, but I don't see how that makes sense here?

• Originally Posted by Keleth
So reading through a pluggin, I'm coming across this syntax:

Code:
`var x = (mx - sImg.offset().left) >> 0`
The math part I get fine, I'm more confused what the ">> 0" means, namely in terms of the assignment?

EDIT: I know >>/<< are used for bitwise operations, but I don't see how that makes sense here?
An ineffective bit shift removes any decimal fraction, so it's probably intended as an equivalent to `var x = Math.floor( mx - sImg.offset().left ); `

• That's... weird...

• Agreed. Anybody who uses crap like that ought to be shot. If you used stuff like that in a professional environment without *REALLY* good justification, the best that would happen to you would be tons of nasty remarks at code review time.

• ">> 0" is equivalent to Math.floor only for non-negative numbers less than 0x80000000.
">> 0" rounds the number towards zero and takes the number from the range from -0x80000000 to 0x7FFFFFFF which is equivalent modulo 0x100000000.
What is the best way to round a number towards zero if it's known the absolute value of the one is less than 0x80000000?

• What is the best way to round a number towards zero if it's known the absolute value of the one is less than 0x80000000?
In other words, if you know the number is a 32 bit integer (but not 0x80000000) but you don't know if it is positive or negative?

Why not create a nice readable JS function?
Code:
```function intValue( n )
{
var r = Math.floor( Math.abs( n ) ); // floor of the absolute value
return n < 0 ? -r : r; // recover the sign as needed
}```
Best part: It even works for values OUTSIDE the normal range of integers!

e.g.,
Code:
`document.write( intValue( -98765432188.888 ) );`
Name it whatever you want to.

• Originally Posted by Old Pedant
Why not create a nice readable JS function?
But ">>0" works much faster than your function and isn't less readable if you know what it does.

• "much faster". Oh, yes. You will save 1 microsecond (MAYBE) each time it is used. On a client computer. [Okay, to be fair, it depends on how powerful the client computer is. But still...]

How many times do you expect to need to use this capability, per second, in your web page? Unless it's at least 1000 times per second I don't see how you would even be able to FIND the time difference.

*IF* you need to use this in some very very very FAST game, then maybe it would matter. I can't imagine in mattering in 98% of all web-based usages.

And if you can REALLY justify using "tricks" like >>0 because you are writing some very fast game, then you can probably also justify finding ways to ensure that you will never be using >>0 with a negative number (e.g., "bias" all your numbers enough that they are always positive?).

• Here:
Code:
```<script type="text/javascript">
var n = -738.781;
var t1, t2;

t1 = new Date();
for ( var i = 0; i < 10000000; ++i )
{
var r = Math.floor( Math.abs( n ) );
if ( n < 0 ) r = -r;
}
t2 = new Date();
document.write("using function: time was " + ( t2.getTime() - t1.getTime() ) + " ms.<hr>" );

t1 = new Date();
for ( var i = 0; i < 10000000; ++i )
{
var r = n >> 0;
}
t2 = new Date();
document.write("using >> only: time was " + ( t2.getTime() - t1.getTime() ) + " ms.<hr>" );

t1 = new Date();
for ( var i = 0; i < 10000000; ++i )
{
var r = n < 0 ? - ( -n >> 0 ) : n >> 0;
}
t2 = new Date();
document.write("using >> with sign check: time was " + ( t2.getTime() - t1.getTime() ) + " ms.<hr>" );
</script>```
On my machine, an older Athlon, using Firefox, 10 million iterations you will notice:

The Math.floor(), etc., version seemed to actually take slightly LESS time (though barely so) than the ">> with sign check" version.

Both of them took only about 2.3 to 2.5 times longer than the bare >>0 alone.

In any case, worst case was about 100 milliseconds for 10 MILLION iterations. That's TEN NANOseconds per usage. Best case (for the >>0 with no check for negative) was around 40 milliseconds.

So, yes, each usage of the sign-checking versions costs you SIX NANOseconds or so.

Is it REALLY worth finding something faster?

• WHOOPS!

Teach me to not do my benchmarking right.

If you really *DO* use a function call (my intValue of prior answer, for example), the times go WAY up for any of the answers.

Turns out the JS in Firefox is smart enough to realize that it is doing the same operation over and over, so it hoists the operation *OUT* of the loop. In other words, it optimizes my test out of existence.

I'll have to retry this with REAL examples.

• Originally Posted by Old Pedant
Turns out the JS in Firefox is smart enough to realize that it is doing the same operation over and over, so it hoists the operation *OUT* of the loop.
I don't think so. This is because some operations are needed for a function call itself which take CPU time. The operation doesn't go out of loop because the time is proportional to the number of iterations.

• Okay...let's try again:
Code:
```<script type="text/javascript">
var nums = [
173.11, -718.88, 9.77, -1001881.11, 43.11, -53.88, 2222222.5, -111111.7, 33.3, -44.4
];

function intValue(num)
{
var r = Math.floor(Math.abs(num));
return num < 0 ? -r : r;
}

var t1, t2, sum;

t1 = new Date();
sum = 0;
for ( var i = 0; i < 1000000; ++i )
{
var n = nums[ i % 10 ];
sum += n;
}
t2 = new Date();
document.write("base loop time was " + ( t2.getTime() - t1.getTime() ) + " ms.<hr>" );

t1 = new Date();
sum = 0;
for ( var i = 0; i < 10000000; ++i )
{
var n = nums[ i % 10 ];
sum += n >> 0;
}
t2 = new Date();
document.write("using >>, time was " + ( t2.getTime() - t1.getTime() ) + " ms.<hr>" );

t1 = new Date();
sum = 0;
for ( var i = 0; i < 10000000; ++i )
{
var n = nums[ i % 10 ];
sum += n < 0 ? - ( -n >> 0 ) : n >> 0;
}
t2 = new Date();
document.write("using >> with time check, time was " + ( t2.getTime() - t1.getTime() ) + " ms.<hr>" );

t1 = new Date();
sum = 0;
for ( var i = 0; i < 10000000; ++i )
{
var n = nums[ i % 10 ];
var r = Math.floor( Math.abs(n) );
sum += n < 0 ? - r : r;
}
t2 = new Date();
document.write("using Math.floor, time was " + ( t2.getTime() - t1.getTime() ) + " ms.<hr>" );

t1 = new Date();
sum = 0;
for ( var i = 0; i < 10000000; ++i )
{
var n = nums[ i % 10 ];
sum += intValue(n);
}
t2 = new Date();
document.write("using function call, time was " + ( t2.getTime() - t1.getTime() ) + " ms.<hr>" );
</script>```
A mildly surprising result:
base loop time was 29 ms
---------
using >>, time was 362 ms
---------
using >> with time check, time was 393 ms
---------
using Math.floor, time was 433 ms
---------
using function call, time was 5439 ms
So, from any of the other results, you should subtract the "base loop time" (as it represents the overhead of the loop, the array access, etc.).

Notice that the last two times are actually using the same basic code. But the difference is that the first one (433 ms) does it inline and the second one (5439 ms) does it by calling a user-defined function.

WOW! The *REAL* overhead here is obviously in simply the existence of the user-defined function. (I also tried creating a function that used the >>0 with sign check inside the function and it showed the same overhead.)

SO...the lesson learned here: If you need performance, write your JavaScript code inline and avoid non-native function calls. Because it is crystal clear, comparing the times for >>0 vs. Math.floor(Math.abs()) *inline*, that there is very little difference between the two. Clearly less than 10 nanoseconds per invocation.

• Originally Posted by oneguy
I don't think so. This is because some operations are needed for a function call itself which take CPU time. The operation doesn't go out of loop because the time is proportional to the number of iterations.
I think I disagree, after seeing my revised benchmark results.

I know that good Java/C++/C# compilers can do this: The easily hoist non-variant operations out of loops and leave in the loop only the code that varies with each operation. I am not overly surprised that modern JavaScript compilers [and don't kid yourself: those *are* JS compilers operating under the covers] can do the same.

You are, of course, right about the function call taking time. [Note that good C++/Java/C# compilers would automatically "inline" any functions as simple as the ones I used, but clearly JavaScript doesn't--maybe can't?--do that.]

Anyway, it looks to me like >>0, with or without the sign check, and Math.floor(Math.abs()) with sign check all operate in between 30 and 50 nanoseconds on my machine. No matter how you cut it, that just isn't much time. And clearly you don't gain enough using >>0 to make it worth the difference in human readability. At least to me.

• Hi Keleth,
It's seem more alien syntax then you think
http://timmywillison.com/pres/operators/

• Old Pedant, thank you for your tests. You agree that perfomance is an advantage of >>0 over using Math.floor with sign checking, don't you? But how valuable this advantage is, is another question. But I can't understand how this
Code:
```var r = Math.floor( Math.abs(n) );
n < 0 ? - r : r;```
can be more readable that this
Code:
`n>>0`
n is used twice instead of once, 2 line of code are used instead of 1, and a temporary variable is used. Furthermore, if we need to use an expression instead of n, which may be long or have side-effects, we need to use another temporary variable.
So, n>>0 is much nore readable for me.

•
Page 1 of 2 12 Last

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•