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

Posted April 30, 2007 at 8:54 AM by Ben Nadel

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

Apr 30, 2007 at 9:29 AM // reply »
6 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.


Apr 30, 2007 at 9:32 AM // reply »
43 Comments

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.


Apr 30, 2007 at 9:47 AM // reply »
11,238 Comments

@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).


Apr 30, 2007 at 10:12 AM // reply »
56 Comments

@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.


Apr 30, 2007 at 10:15 AM // reply »
79 Comments

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


Apr 30, 2007 at 10:16 AM // reply »
79 Comments

Tony - great idea!


Apr 30, 2007 at 10:43 AM // reply »
11,238 Comments

@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!


Apr 30, 2007 at 2:29 PM // reply »
56 Comments

thanks for props guys.

But like most of the cool ideas in my head, they all have an originating source, though most of the time I don't remember where :P

Is a discussion on the CF Cookbook about this topic:

http://www.coldfusioncookbook.com/entry/53/How-do-I-determine-if-a-number-is-even-or-odd


Apr 30, 2007 at 2:58 PM // reply »
11,238 Comments

@Tony,

You might not have invented it, but you sure get credit for pointing it out to me:

http://www.bennadel.com/index.cfm?dax=blog:668.view

:)


Nov 25, 2007 at 3:06 PM // reply »
1 Comments

There is a faster way to do Even/Odd checks

int OMask = 1;

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

-Chris


Nov 25, 2007 at 4:04 PM // reply »
11,238 Comments

@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.


Jun 30, 2009 at 1:01 PM // reply »
19 Comments

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!


Jun 30, 2009 at 1:33 PM // reply »
11,238 Comments

@Will,

I am not sure what you mean?


Jun 30, 2009 at 4:29 PM // reply »
19 Comments

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.


Jul 1, 2009 at 8:23 AM // reply »
11,238 Comments

@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.



Post A Comment

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.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 20, 2013 at 4:38 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Dana, Your confusion is well founded, since this is a very confusing features. In fact, it ONLY works if you use array notation. Meaning, that this: arrayToList( query[ "columnName" ] ) ... read »
May 20, 2013 at 4:34 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
I was thinking chicken and the egg, I wouldn't have expected it to work in the valuelist going in I guess. Maybe I just need a beer, long day :) ... read »
May 20, 2013 at 4:29 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Dana, That's if you're trying to reference a specific row. In this case, we're trying to reference the entire query column as one cohesive value. So, you are correct that if you wanted to output a ... read »
May 20, 2013 at 4:24 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
I thought when you used array notation to reference queries you always had to have the row or it would throw a similar error as well? ... read »
May 20, 2013 at 11:45 AM
Using jQuery's Animate() Step Callback Function To Create Custom Animations
This is really useful. I found out that you don't actually have to use a dummy css property (surprisingly). To animate a property in a linear-gradient for instance I did this this.css('someLinearGra ... read »
May 20, 2013 at 10:51 AM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Josh, Oh snap! You're totally right! I'm not sure I've ever tried that. I did know that you can call a number of other array-methods on ColdFusion query columns: http://www.bennadel.com/blog/167 ... read »
May 20, 2013 at 10:45 AM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Ben - I believe you can achieve the same functionality with ColdFusion's built in ArrayToList() function. ArrayToList( users[ "id" ] ); ... read »
May 20, 2013 at 10:21 AM
My Experience With AngularJS - The Super-heroic JavaScript MVW Framework
Is there any error logging and handling framework in angularjs, if not then in what way I can do this. ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools