Odd or Even in ActionScript

Just saw a great post over here: http://www.coldfusioncookbook.com/entry/53/How-do-I-determine-if-a-number-is-even-or-odd?

Actually, it was the first comment that was awesome. Were I to decide if a number is odd or even in ActionScript, I’d do the same thing the original post did (translated to AS):

iseven = ((num % 2) == 0)

The comment suggested a faster way using bitwise operators. Translated to AS it’s this:

iseven = ((num & 1) == 0)

Makes sense when you look at binary numbers:

001 = 1

010 = 2

011 = 3

100 = 4

101 = 5

Each of the odd numbers has a 1 in the far right column. The even numbers have 0 there. Mask it with “& 1” and you can see which it is.

A pretty minor difference syntactically, but bitwise operators are FAST. I’m not sure how mod (%) works internally, but I’d guess it does a fair amount of calculation.

Nice elegant solution.

This entry was posted in General. Bookmark the permalink.

17 Responses to Odd or Even in ActionScript

  1. Miha L says:

    Nice one! 😀

  2. cedric says:

    Hi Keith!
    ohohhh I never thought I would once do something useful for you 🙂
    I am such a fan of your book, and findings that I feel on fire 😉
    small, but cool
    I am happy

  3. cedric says:

    drop my comment, I am out 😉

  4. darron says:

    That was my comment. What, no link to the original source? 🙂

  5. kp says:

    Sorry Darron, I didn’t even notice who wrote it. And let me correct myself and point out that it was the SECOND comment that was so awesome.
    Hear ye! Hear ye! Let it be known to all in the land that Darron Schall is master of all things bitwise!
    🙂

  6. darron says:

    Haha.. save that proclamation for when I show everyone what’s been up my sleeve for awhile… if I can ever finish it!

  7. Craig says:

    Brilliant! I’d been playing with modulo switching (on/off) in place of conditionals. Just replaced it with:

    bitSwitch = (switchCount & 1);// bitwise switch
    switchCount++;

    Much thanks to Darron and Keith!

  8. Aral says:

    Yep, Darron is definitely bit wise! *Badabing* *Badaboom* Thank you, thank you!.. 🙂

  9. james gauthier says:

    at least on my machine
    isEven = !(i%2)
    takes 3/4ths the time of
    isEven = !(i&1)
    in action script 2. sad but true.

  10. kp says:

    Actually on my machine, % and & are just about equal. 10000 iterations both give about 100 ms give or take 2 or 3 ms. I don’t know Darron, your crown may be in jeapordy.

  11. Danny Miller says:

    OUTPUT:
    Avg of 100 runs of 10000 iterations
    & = 98.4444 ms
    % = 97.295 ms

    :-\.

    Maybe it runs different on different versions of flash?
    Hmm…
    Where is Mike Lyda when you need him?
    -Danny

  12. Juicelahoma says:

    From the Free On-line Dictionary of Computing:

    Where the second argument is a power of two, the result can be
    calculated much more quickly using bitwise and with the
    appropriate bit-mask.

  13. james gauthier says:

    OK now I’m really curious. Did you guys subtract the loop and assignment time? My benchmarking looked like this.


    function test1() {
    var isEven:Boolean;
    var t1 = getTimer();
    for (var i = 0; i!=100000; i++) {
    isEven = !(false);
    }
    var t2 = getTimer();
    for (var i = 0; i!=100000; i++) {
    isEven = !(i%2);
    }
    var t3 = getTimer();
    trace('% result: '+(t3-t2-(t2-t1)));
    }
    function test2() {
    var isEven:Boolean;
    var t1 = getTimer();
    for (var i = 0; i!=100000; i++) {
    isEven = !(false);
    }
    var t2 = getTimer();
    for (var i = 0; i!=100000; i++) {
    isEven = !(i & 1);
    }
    var t3 = getTimer();
    trace('& result: '+(t3-t2-(t2-t1)));
    }
    test1();
    test2();
    test1();
    test2();

  14. cedric says:

    % result: 79
    & result: 41
    % result: 78
    & result: 39

  15. james gauthier says:

    the investigation continues…
    flash 7
    % result: 34, & result: 54, % result: 34, & result: 56

    flash 8
    % result: 40, & result: 31, % result: 39, & result: 31

  16. darron says:

    On a machine code level, “& 1” is much faster than “% 2”. There is a machine opcode for bitwise and, which means it can happen in 1 cycle. There is no opcode for modulo, it’s going to take multiple cycles to get a value (modulo does repeated subtraction as far as I know). You’ll really notice the difference in large numbers. Imagine subtracting 2 from 1000000 (how many cycles is that?) vs 1 cycle for “& 1”.

    So, if you’re not seeing any speed differences between the two, its probably the result of code in the Flash Player that isn’t optimizing the instruction. Might have something to do with coercing a variable to a number type which could be a long operation that negates the speed benefits of the fast “and”.

    I suspect that ActionScript 3 does a better job at converting the “& 1” on the machine code level.

Leave a Reply