Lesser Known Operators: Modulo (%)
Modulo is one of the multiplicative operators, a category whose members take two operands and perform a multiplication, division, or modulo operation on them. Obviously, in this case the operation performed is modulo, so let’s take a look at what that means, especially since this operation can be useful in a number of unexpected ways.
What it does
Modulo divides one number into another and returns the remainder, if any. For example, 4 divided by 2 is 2, with no remainder; therefore, 4 modulo 2 equals 0. Looking at that another way, 2 goes into 4 two times evenly. The result of the modulo operation is zero because there is no remainder.
Here’s another. 10 modulo 7 is 3. Why? Because 7 goes into 10 once, with a remainder of 3. To be clear, it makes no difference how many times one operand goes into the other. The only thing modulo cares about is the remainder. 1,000 modulo 7 is 6 because 7 goes into 1,000 one hundred forty-two times (who cares?), with a remainder of 6.
5 mod 2 is 1 … because 5 / 2 leaves a remainder of 1
13 mod 2 is also 1 … because 13 / 2 leaves a remainder of 1
I think you get the idea.
How is this useful?
Telling odd or even
There are times you may want to know if a certain number is odd or even. You might, for example, wish to alternate row colors in a table, making every odd row yellow. Modulo tells you right away which is which: if a number mod 2 equals zero, it’s even.
Consider the number 6. Is 6 odd or even? Common sense tells us it’s even. 6 mod 2 (that is, 6 % 2) equals 0, so evaluate that in an if statement …
var num:Number = 6;
if (num % 2 == 0) {
trace ("even");
} else {
trace ("odd");
}
Building grids
Modulo comes in handy if you need to stack items in columns and rows. You might, for example, want to sort a number of movie clips (perhaps they represent icons) into rows of five.
The following sample code assumes you have a small movie clip (5×5 pixels, say) in your Library with a Linkage id of “square.” Two variables, paddingX and paddingY, are used to position a dozen instances of this clip on the Stage. These variables both start at zero, so the first clip is placed at the upper left corner (0,0). After that, paddingX is increased by ten with each iteration. If the number of this iteration mod 5 equals zero, we know the row contains five items, so paddingX is reset to zero and paddingY is increased by ten, which makes a new row.
var paddingX:Number = 0;
var paddingY:Number = 0;
for (var i:Number = 1; i <= 12; i++) {
var mc:MovieClip = this.attachMovie ("square", mcSquare + i, i);
mc._x = paddingX;
mc._y = paddingY;
paddingX += 10;
if (i % 5 == 0) {
paddingX = 0;
paddingY += 10;
}
}
Formatting time
There are twenty-four hours in a day, or two twelve-hour half-days. Depending on your preference, you might refer to 15:00 o’clock as 3:00pm. Hours are based on a duodecimal (base-12) system, which means they cycle at twelve, rather than at ten, like normal decimal counting. Minutes and seconds are sexagesimal (base-60), which complicates things even more. Common sense tells us that if we start with 1:45, we need to increment that 1 to a 2 when the 45 eventually becomes 60 (and, in turn, must reset that 60 back to 0).
You may already see the pattern, here. If you have a known number of seconds — say, 124 seconds — you can find out how many minutes and seconds that is by first dividing the number by 60, then modding it by 60.
124 / 60 = 2.066666 minutes (just round that down)
124 % 60 = 4 seconds
Therefore, 124 seconds equals 2 minutes and 4 seconds.
P.S. I’m a strong advocate of the ActionScript 2.0 Language Reference and often encourage people to head there first. The thing about operators is that they’re usually just punctuation marks, which makes them a bit tougher to locate. Best bet: just search the word “operators” — you’ll see the whole list.
July 24th, 2006 at 8:49 am
You turned me on to this a while back and I’ve thanked you, if only telepathically, every time I’ve had opportunity to use it. The biggest help has been in formatting Crystal reports by shading every other line using the odd/even technique.
Good stuff, man… good stuff.
July 24th, 2006 at 11:25 am
Cross polination is a darned cool thing in programming.
August 30th, 2006 at 3:36 pm
I am trying to shade every other line in Crystal Reports. Can you tell me if their is a line counter or something I can use to test for odd and even lines?
Gordon
August 30th, 2006 at 7:41 pm
Gordon,
I’ve heard of Crystal Reports, but have never used it — in any case, it’s not related to Flash!
From what I’ve heard, Crystal Reports is very robust; there may very well be a built-in method for returning whether a particular line number is odd or even, but if there isn’t, use relevant syntax for the example under the “Telling odd or even” heading above.
September 28th, 2006 at 11:41 am
did you figure out how to do it
September 28th, 2006 at 11:52 am
nirav,
How do to what — the Crystal Reports thing?
September 29th, 2006 at 12:35 am
“For example, 4 divided by 2 is 0, with no remainder; therefore, 4 modulo 2 equals 0.”
Actually, 4 divided by 2 is 2
September 29th, 2006 at 12:21 pm
Matt,
Ha! Woops. Thanks, man. Updating the article now.
October 3rd, 2006 at 1:15 pm
I’m going to try and convert _currentframe of a SWF video, to HH:MM:SS:frames
where frame is 29.97.
I tihnk i have the tools between this post and AS dictionary.
but if someone has doen it please post.
October 3rd, 2006 at 4:17 pm
Icarus,
Wow! For what you’re doing, I would probably use specifically video-related properties, such as
FLVPlayback.playheadTimeor, say,NetStream.time(see related classes in the ActionScript 2.0 Language Reference for details).If you really want to convert a timeline-based video to HH:MM:SS:frames, you’re going to have to be prepared for inaccurate results, not only because the timeline cannot have fractional frames, but also because the arithmetic may be more or less “chunky” depending on the framerate ratios.
That said, you’d have to know your SWF’s framerate going in. Let’s say your SWF’s framerate is 24fps. If the SWF has 100 frames — because that’s how may frames the video requires — then the video takes approximately 4.17 seconds to play from start to finish (100 frames divided by 24fps = 4.17). If you’re at frame one, zero seconds have passed. If you’re at frame 100, 4.17 seconds have passed. With me so far? If you’re at frame 50, 2.09 seconds have passed.
So take note of the SWF’s
_currentframevalue and compare that against its_totalframesvalue to find your ratio.Then use that ratio to determine seconds.
November 20th, 2006 at 12:25 am
Thank you, exactly what I needed to learn. Great site, keep it up.
November 20th, 2006 at 8:29 am
Thanks, Paul!
January 22nd, 2007 at 11:11 pm
“var ratio = _totalframes / _currentframe
// e.g. 100 / 50 = 0.5″
Shouldn’t it be _currentframe / _totalframes
100 / 50 is … whoops! 2
and also, you can simply divide the frame you are at by the frame rate to get seconds. We see that this is identical to the originally proposed method… (_currentframe / _totalframes) * (_totalframes/24) = _currentframe / 24
January 23rd, 2007 at 8:19 am
NSurveyor,
Haha … yes, 100 / 50 is 2. Man, I’m a goof. That’s two simple arithmetic errors for me in either the article or the comments.