Practical uses for the modulo operator


I was introduced to the modulo operator in my first real programming job (longer ago than I care to admit). The problem I had was that I needed to generate a calendar as a simple HTML table (remember when all website layout was done with tables?) and needed to layout columns in multiples of 7.

I shared my dilemma with Felix, a more experienced and knowledgeable programmer at work who taught me about the modulus operator.

The modulus operator returns the remainder of a division of one number by another. In most programming languages, modulo is indicated with a percent sign. For example, "4 mod 2" or "4%2" returns 0, because 2 divides into 4 perfectly, without a remainder. "5%2", however, returns 1 because 1 is the remainder of 5 divided by 2 (2 divides into 5 2 times, with 1 left over).

That doesn't sound like much, but it turns out that knowing the remainder of a division is immensely useful in certain situations.


Example 1: Is a number even?

Since any even number divided by 2 has a remainder of 0, we can use modulo to determine the even-ess of a number. This can be used to make every other row in a table a certain color, for example.

for (x = 1; x < 11; x++) {

    if (x%2 == 0) {
        // Yes! this is an even row
        rowColor = #CCCCCC; // grey
    
    } else {
        // This is an odd row
        rowColor = #FFFFFF; // white
    }
}


Example 2: Do something every nth time.

If you have a for loop and want to report on the state of the loop, but not every cycle through, you can use modulo:

for (x=0; x <100000; x++) {

    // do regular stuff here
 
    // do something special every 9th time through
    // the loop
    if (x % 9 == 0) {
        // important stuff here
    }
}

Example 3: Prepare seconds for display as Hours, Minutes and seconds.

If you need to turn an elapsed number of seconds into Hours, Minutes and Seconds, modulo comes in handy.

hours:int   = seconds / 3600;
minutes:int = (seconds / 60) % 60;
seconds:int = seconds % 60;

starting with 582 seconds:

hours   = 582 / 3600 = 0 // integer would round this to 0
minutes = (582 / 60) % 60 = (9.7) % 60 = 9
seconds = 582 % 60 = 42

Thus, 582 seconds is 9 minutes, 42 seconds.


Example 4: Force a number to be a multiple of another number

Another way of thinking of this example is forcing a number to be evenly divisible by another number.

Let's say you need to have a number that is always a multiple of 10. You can use modulo in this way to accomplish it:

multipleOfTen = x - (x % 10);

By subtracting the remainder of a value x divided by 10 from x we get a value that is always divisible by 10. It's a neat mathematical trick.

For x=1 through x=9, for example, x%10 is always x. Thus:
multipleOfTen = 1 - (1 % 10) = 1 - (1) = 0;
multipleOfTen = 2 - (2 % 10) = 2 - (2) = 0;
multipleOfTen = 3 - (3 % 10) = 3 - (3) = 0;
...
multipleOfTen = 9 - (9 % 10) = 9 - (9) = 0;

once we hit 10, we get:
multipleOfTen = 10 - (10 % 10) = 10 - (0) = 10;

and once we hit 20 we get:
multipleOfTen = 20 - (20 % 10) = 20 - (0) = 20;


But...how is this useful? Well, imagine that you need to work with a data structure that is made up of values grouped in multiples. One such data structure is a ByteArray representing an audio file. Often times programming languages give you access to binary files as ByteArrays so that they are easy to operate upon (upload, write to the file system or perform data conversions).

Now, if you record 32-bit audio, you're capturing data 4 bytes at a time. That means that every audio sample, the smallest unit of data, is 4 bytes wide. Indexes 0 through 3 of the ByteArray would represent one sample.

If you were to split a byte array representing a 32-bit audio file in the middle of a 4-byte unit, you would "break" the audio file. When played back, you would either get an end of file error and/or it would sound like a screech.

In order to safely edit the audio ByteArray, you can only edit in multiples of 4, at the beginning or end of a 4 byte block, not in the middle.

So, let's say we want to trim some bytes from the start of the audio file. What's a safe starting index in the array?

Since the data is chunked in groups of 4, we can say:
safeStartIndex = startIndex - (startIndex%4)

A start index of 0 would yield a safeStartIndex of:
safeStartIndex = 0 - (0%4) = 0 - (0) = 0

A start index of 1 would yield:
safeStartIndex = 1 - (1%4) = 1 - (1) = 0

A start index of 2 would yield:
safeStartIndex = 2 - (2%4) = 2 - (2) = 0

A start index of 3 would yield:
safeStartIndex = 3 - (3%4) = 3 - (3) = 0

A start index of 4 would yield:
safeStartIndex = 4 - (4%4) = 4 - (0) = 4

Notice that by using modulo, we can automatically adjust non-safe ByteArray indexes to an index which is divisible by 4 and won't split the audio file represented by our array in the wrong place (ie. in the middle of a sample group).

Final Words

The WatchHogStories blog has another way of describing modulo which I really like. As Dotun, the author of the blog, says (with a slight modification):

* a is zero or a positive number.
* n is a positive number.
* if a / n equals a whole number then a % n  always equals 0
* if a is and less than n then a % n always equals a
* if a is greater than n then a % n always equals a value between 1 and n-1

HTML script tags can not be atomic/self-closing

Recently I completed a project where I converted an Actionscript form generation system I wrote for my wife's business into Javascript.

I've been writing Javascript on and off for the last, almost, 20 years. For easy coding, I started with all my code and css styles in the same html file, but eventually broke up everything into individual files.

I placed the stylesheet in its own file and loaded it using a standard <link> tag:

<link id="primaryStylesheet" rel="stylesheet" type="text/css" href="path/to/my/fancy/stylesheet.css" />

Notice how the I used the self-closing (atomic) version of the <link> tag (ends with "/>" rather than with a closing "</link>").

Then it was time to load in all the Javascript which was now in its own set of external files. I used a standard <script> tag for that:
<!-- DOESN'T WORK -->
<script type="text/JavaScript" src="/awesome/library.js" />

However, I was surprised to find that while my stylesheet loaded without a problem, my Javascript files did not. I knew this not because I got an error like "Javascript files did not load", but because the scripts that I knew to work and do something on screen no longer did anything. After a little investigation, I discovered they weren't in memory at all.

A little googling brought me to an entry on Siderite's Blog that explains he had the same problem and discovered that the W3C DOM recommendation states the following about the script tag:

Start tag: required, End tag: required

Thus, it can't be an atomic/self-closing tag. Browsers respect that, though they don't provide any error feedback, instead failing silently.
<!-- Works! -->
<script type="text/JavaScript" src="/awesome/library.js"></script>

So, thanks Siderite for reminding me that it pays to read specs. :-)

Add a stereo jack to Sennheiser RS-120 Wireless Headphones

Before

After
Background:

This is a simple project that I did over a couple of hours one Saturday. I decided to make a blog entry about it because I think it makes a good project for someone just starting in electronics.

What I wanted to do was add a stereo output to a pair of Sennheiser RS-120 wireless headphones my wife and I use at home when we don't want to disturb each other.

For normal day to day use, the Sennheisers work great. They have long range, the batteries last forever, and they're comfortable for extended use. However, they don't lend themselves to being worn during workouts.

I have an elliptical machine at home and can't bear to exercise unless I'm distracted by the TV. Since the elliptical machine is rather noisy, I either have to turn up the TV volume--which my wife doesn't like--or wear the headphones, which I don't like because my ears sweat all over the pads. Yeah, I know, gross.

The solution, to keep my wife happy ("Happy wife, happy life" as the saying goes) and to have a more comfortable workout, was to add a jack to the Sennheisers so that I could use my own exercise-friendly earbuds, while still enjoying wireless audio.

Headphone circuitry layout:

The wireless, audio and charging circuitry of the Sennheiser RS-120's is split across the left and right ear cups.

As illustrated in the drawing below, the left ear cup printed circuit board (PCB) has the power switch, houses the rechargeable batteries and, of course, the left speaker. The right ear cup PCB has the wireless receiver, volume and tuning knobs and the right speaker. Wires run through the headband carrying power from the left ear cup to the right, and an audio signal from the right pcb to the left PCB and speaker.

At first I thought I'd have to run extra wires through the headband, as I wasn't sure where the left speaker amplification was happening--did the left audio signal already "arrive" amplified from the right side, or did the left PCB do final amplification. To determine what wired carried what signal, I traced connections on the left and right PCBs and used my multimeter to detect changing voltage values off the leads I suspected carried the audio signals. It would have been better for me to use an oscilloscope, but I don't have one. However, I did connect the leads I suspected carried the audio signals to my earbuds using alligator clips.

Anyway, I determined that right PCB did all the amplification and sent the left speaker audio signal over to the left ear cup. I could do all my modifications on the right side without needing to run additional wires through the headband. Here's a simplified circuit diagram:


What you'll be doing

You will be adding a switch to your headphones that will let you switch between two sets of speakers: the internal ones and an external set (via a stereo jack).

The circuit board in the right ear cup has electronic components and solder points on both sides. On the front side, there is little but two solder points that connect directly to the right speaker.

The back side of the right PCB has many components, including two potentiometers for volume and tuning and five solder pads at the top of the circuit board. The two left-most solder pads connect to wires which go through the headband and eventually connect to the left speaker.

We will be disconnecting one of the wires to the left speaker on the back of the PCB and one of the wires to the right speaker on the front of the PCB and connecting them up to the switch. Then we'll run wires to the two sets of speakers off the switch.

 Here's a diagram showing the basic circuit:

Notice that we'll be using a DPDT switch. That stands for "Double-Pole, Double-Throw". Double-pole means that the switch handles two circuits, while double-throw means there are two positions to the switch. Looking at the circuit diagram above, the two circuits are the left and right audio signals.

What you'll need
  • 1/8" panel-mount stereo headphone jack, 3 conductor.
    This is what you'll plug your external headphones into. Panel mount means that the top of the jack as a nut so that you can screw it into a properly-sized hole. The 3 conductors are for left, right and ground connectors.
    Radio Shack model 274-249.

  • DPDT Micro-mini toggle switch.
    DPDT stands for "double-pole double-throw". Double-pole means the switch handles two circuits, and double-throw means that the switch has two positions. I chose this switch because I wanted to handle two circuits (the left and right audio circuits) and two positions (to select either the internal speakers or the stereo audio jack). You'll want a micro-mini switch because there isn't much room in the ear cups.
    Radio Shack model 275-626.

  • Stranded hookup wire (22 to 26 gauge)
    This is just what it sounds like: it's wire. Get the stranded type (as opposed to solid copper), as it's easier to bend and use. Since you'll be working in a tight space, stranded wire will be better.
    Radio Shack model 278-1224.
  • Soldering Iron
  • Solder

Step-by-Step
Circuit Diagram of finished connections

  • Remove the ear pad on the right side by rotating it.
  • Unscrew the speaker panel.
  • Remove the screws holding down the printed circuit board.
  • Using the soldering iron, disconnect the speaker cable on the lower solder point on the front of the PCB by heating it until you can pull the wire off.
  • On the back of the PCB, heat the left-most solder pad up top until you can disconnect the wire connected to it. This is one of the two wires that connects to the left speaker.

  • Drill a hole at the top of the right ear cup the size of the switch top. I made successively larger holes until the switch fit through. The reason I put the switch up top is so that I wouldn't accidentally flip the toggle if I leaned back on my couch. Don't screw the switch into place yet. It will be easier to solder all the wires that way.
  • You will also need to make a hole for the stereo jack. I placed mine toward the bottom of the ear cup. As with the switch, don't screw it into place.
  • Solder a wire from the now free front solder pad to one of the center posts on the DPDT switch. This is the right channel audio signal.
  • Solder another wire from the left-most free solder pad on the top of the PCB back to the other center post of the switch. This is the left channel audio signal. 
  • Solder a wire to each of the four remaining posts on the switch. You will be connecting each set of wires to the speakers, and the other set to the stereo plug.

  • Pick a set of wires on either side of the center posts of the switch. We're going to connect those two wires to the left and right speakers. Select the wire that is adjacent to the center post which is connected to the left audio channel (it's the center post which is connected to the pad on the back side of the PCB). In the diagram of the circuit, all the left channel wires are in GREEN. Solder this left channel wire to the wire which leads back to the left speaker. Remember that the wire that connects back to the left speaker used to soldered to the back of PCB. To keep this wire to wire connection from causing a short circuit, use some electrical tape.

  • Now solder the right channel from the same side of the switch to the free solder pad on the right speaker. In the circuit diagram, the right channel audio wires are in BLUE.
  • Test that you can hear audio out of the speakers when the switch is flipped to the correct side.
  • Now we have two wires left on the switch. These are the right and left channels that we are going to solder to the stereo jack.
  • Take the wire that is adjacent to the center post which is connected to the left audio channel. You will connect this to the left channel connector on the stereo jack. Typically the left channel on a set of headphones is the connector that makes contact with the tip of the stereo plug. Take a look at the diagram for reference.
  • Now you have one wire remaining coming off the switch. This is the right channel and it should be soldered to the connector in the stereo plug that makes contact with the center part of the stereo plug. Depending on the configuration of the stereo jack you have, the left and right connectors might be hard to pick apart. Refer to the packaging for the jack to figure out which is which.
  • Finally, you will need to solder a return wire from the stereo jack common or ground connector back to the PCB. As shown in the diagram, I soldered the jack common to the front of the PCB, to the top solder pad that feeds the right speaker.
  • Test the internal and external speakers by flipping the switch back and forth. If you soldered everything correctly, you'll alternatively hear audio from the built-in speakers and through the stereo jack. 
  • Carefully screw the switch and stereo jack into place and pack all the wires into the ear cup.
  • Finally, screw the PCB and then speaker back into place and twist the ear pad back on.

Additional modification

It was pointed out to me by my friend Josh, who knows more about electronics than I do, that I could have used a 4 conductor stereo jack and gotten rid of the toggle switch entirely. A 4 conductor jack acts like a switch as well. The act of inserting a stereo plug into the jack makes it behave like a switch being flipped, so that you can go from the internal speakers to the external audio jack without the need of a separate switch like I used.

I like the retro look and feel of the toggle switch, however, so I'm glad that I used it in the project.