Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at CFUNITED 2009 (Lansdowne, VA) with:

And On The Seventh Row, MOD Created 1, And It Was Good

By Ben Nadel on
Tags: ColdFusion

On Ray's Friday Puzzler, it came up that not everyone knows what the MOD (or Modulus) operator is in math. This is one of those things that once you know it, you can't imagine how you lived with out it. The MOD operator does a fairly simple thing: it divides two numbers and returns only the remainder.

To demonstrate how this works in a practical sense, let's run this code:

  • <!--- Loop over value range. --->
  • <cfloop
  • index="intValue"
  • from="1"
  • to="15"
  • step="1">
  •  
  • <!---
  • Get the result of this Value MOD'ed by 3.
  • Remember, this will divide 3 into the value
  • and return the remainder.
  • --->
  • #intValue# MOD 3 = #(intValue MOD 3)#<br />
  •  
  • </cfloop>

Running the above code, we get:

1 MOD 3 = 1
2 MOD 3 = 2
3 MOD 3 = 0
4 MOD 3 = 1
5 MOD 3 = 2
6 MOD 3 = 0
7 MOD 3 = 1
8 MOD 3 = 2
9 MOD 3 = 0
10 MOD 3 = 1
11 MOD 3 = 2
12 MOD 3 = 0
13 MOD 3 = 1
14 MOD 3 = 2
15 MOD 3 = 0

Notice that we can see a sequence coming through: 1,2,0. The sequence is as long as the number we are using to MOD. This is because every Nth value should be evenly divisible by (N) and then the remainder gets "reset."

This can be a headache saver for ColdFusion query output when you want to format alternating rows. To figure out which row you are on (odd vs. even), all you have to do is MOD the current row by 2. If 2 divides evenly into the row number (and thereby resulting in a remainder of zero), we are on an even row. If we MOD by 2 and have a remainder, we must be on an odd row.

  • <!--- Loop over query. --->
  • <cfloop query="qData">
  •  
  • Row #qData.CurrentRow# is:
  •  
  • <!---
  • Check to see if this row is even or odd.
  • If this row number MOD 2 has a reminader
  • (evaluates to TRUE in ColdFusion), then
  • we are in an odd row.
  • --->
  • <cfif (qData.CurrentRow MOD 2)>
  •  
  • ODD
  •  
  • <cfelse>
  •  
  • EVEN
  •  
  • </cfif>
  •  
  • </cfloop>

Running the above, we get:

Row 1 is: ODD
Row 2 is: EVEN
Row 3 is: ODD
Row 4 is: EVEN
Row 5 is: ODD
Row 6 is: EVEN

Tons of stuff has been written about the Modulus operator. It's totally awesome. When working on Ray's puzzler, I was having a huge mental block trying to figure out how to get rid of the zero in my sequence. Here is a great resource I found that talks about using and manipulating sequences using the modulus operator.

Go forth and MOD.




Reader Comments

GREAT headline.

Btw, I never got to comment on your issues with being a senior programmer. I am not sure what that means given my being self employed or working for interweb startups and small dev companies for the last 10 years. But I have been reading your blog for the last 4-5 months and I can truthfully say that you are a damn good programmer. You have taught me quite a bit.

Reply to this Comment

Another handy use: creating a specific number of columns. I use this all the time since I find myself creating "sets" of checkboxes. If I have 11 checkboxes it's easier to read if they're laid out so that there are 2 rows of 4 and one row of 3.

To do that, I usually give the parent element a pre-defined width and float it to the left. Each successive checkbox then is added to a single row. I can then just test the current index MOD 4 (current index % 4 in php and others) and, if the value is 1, set the element class to "startrow" or some such. To that class I apply clear: left to force the creation of a new row.

As you say...handy.

Reply to this Comment

@Cozmo,

Thanks for the kind words. Glad that I can help out.

@Rob,

Yeah, excellent use case. Along those same lines, outputting over a calendar can be quite helpful (MOD 7).

Reply to this Comment

@ben,

learned this trick a LOOOONG time ago:

Instead of using MOD to find out if a number is ODD or EVEN, use BITAND(). An example:

BitAnd(8,1) would return 0 which means it's EVEN
BitAnd(5,1) woudl return 1 which means it's ODD

Using the MOD function, CF must internally perform a lot of calculations in order to see if there is a remainder or not. BitAnd just uses BitWise logic to see if the number's first bit is a 0 or 1.

I doubt you will see a performance difference on small sites, but if your pumping out 10,000 could make a difference.

Reply to this Comment

Using mod is much better than the:

[cfif color is "white"]
[cfset color = "gray"]
[cfelse]
[cfset color = "white"]
[/cfif]

[tr bgcolor = "#color#"]

that I've seen in places...

BTW, I loved the headline too

Reply to this Comment

@Tony,

That is very slick! Bit manipulation is one of those dark arts that I think very few people (including myself) really understand how to take advantage of. I have used Bits as a way to group "flags" for objects, but nothing like this.

Thanks for the awesome tip. And yes, I can see this would be a much better performance feature (as division never actually needs to take place). Cool!

Reply to this Comment

There is a faster way to do Even/Odd checks

int OMask = 1;

if( (someotherint & OMask) == OMask)
numberisodd
else
numberiseven

-Chris

Reply to this Comment

@Chris,

There is no bit-wise AND operator in ColdFusion. Instead, you would have to use the BitAnd() method:

<cfif BitAnd( qData.CurrentRow, 1 )>
... ODD ...
<cfelse>
... EVEN ...
</cfif>

As far as this method being faster, I suppose it would be because it's not actually performing any mathematical dvision (as would be required for MOD). Really, we are just taking the binary representation of the number and examining the first digit. I assume that this would be a constant speed no matter how large the number. Thanks for the good tip.

Reply to this Comment

I just wrote something similar before stumbling upong this post. I had a hard time deciphering MOD so I made this script so I could see how it works visually.

<cfloop from="1" to="10" index="i">
<cfoutput>
<h3>MOD #i#</h3>
<cfloop from="1" to="10" index="z">
<cfset res = z MOD i />
<li>#z# MOD #i# = #res#</li>
</cfloop>
</cfoutput>
</cfloop>

I was trying to get it to execute on the third iteration. What I found is doing x MOD y = 0, where y is your desired iteration (in my case 3) seems to work in any case. Run the code and see for yourself!

Reply to this Comment

I'm referring to using MOD in a cfoutput query, where you'd need every other row highlighting, or a line break after every third item, or fifth. I've found the easiest and most legible way is to do :
currentRow MOD 2 EQ 0
or
currentRow MOD 3 EQ 0
or currentRow MOD 5 EQ 0 respectively.

The only need I've had for MOD thus far has been in a query loop, so I guess it's a narrow perspective.

Reply to this Comment

@Will,

Ahh, gotcha. Yeah, I think that's how most people need to use MOD. The only time I've had to use it otherwise is for sequential number outputs of some sort.

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.