Currently geeking out as WordPress developer at WebKinder and student of computer science at ETH.

# Bug report: Compute the 5 next months with modulo arithmetic

December 6, 2017

This post is about a stupid bug I wrote and what I learned from it. The goal of this format is to reduce the chance repeating a mistake and possibly prevent someone else from making it entirely. I will try to write more of these posts because I inevitably will write more incorrect code. Some errors are simple and easy to explain while others are more subtle and require more context. The one I write about today belongs to the former type. In fact it is a pretty embarrassing one but that’s the whole point right?

I encourage anyone to write this kind of post. If you do, please let me know so I can learn from your mistakes!

## The problem

Given a month represented by a number between 1 and 12, compute the number representations of the 5 months following it. Here are a few example inputs and outputs:

$$5 \mapsto \{ 6,7,8,9,10 \}$$

$$8 \mapsto \{ 9,10,11,12,1 \}$$

$$12 \mapsto \{ 1,2,3,4,5 \}$$

It is a purely mathematical function that needs to be implemented. And a simple one indeed, but hey: I managed to get it wrong.

## The bug

Now comes the embarrassing part, here is my fairly old PHP code trying to implement this:

// Input month given in $month$next_months = [];
for($i = 1; i < 6; ++i) {$next_months[] = $month +$i % 13;
}



This is completely wrong. Probably the worst mistake is that I got operator precedence wrong: Modulus (%) binds stronger than addition (+). Therefore $i % 13 is evaluated first and will simply result in $i because it is always smaller than 13. But even if you correct the order of operations with parentheses, the result will still be wrong. I honestly cannot remember how I came up with this, but I probably thought things will get refactored and cleaned up anyways. It often doesn't until things start to break.

## The fix

Since the error was purely mathematical, the fix is too. There are many other possible correct solutions involving PHP built in functions handling dates. However, I decided to keep this purely arithmetic. I simply wanted to know the mathematical function that I am trying to implement. It is enough to take a step back and realize that the function for the next month behaves almost like the modulo 12 function. It maps an integer onto its remainder when divided by twelve:

$$x$$ 0 1 2 $$\dots$$ 11 12 13 14 $$\dots$$
$$x \mod 12$$ 0 1 2 $$\dots$$ 11 0 1 2 $$\dots$$

I say almost, because it is shifted by one. We do not have a month for the integer 0, but we do have one for 12. But that is just a matter of identifying things! So I can map the numbers representing months onto these by subtracting one. First I subtract one to get the corresponding number in the system above. Then I perform the modulo 12 operation and transform the result back into the original space by adding one:

$$nextMonth(x) := ((x - 1) \mod 12 ) + 1$$

The corresponding PHP code then becomes:

// Input month given in $month$next_months = [];
for($i = 1; i < 6; ++i) {$next_months[] = (($month - 1 +$i) % 12) + 1;
}



Again, I am not saying this is the best way to do this. At least for me it obviously is not, because I got it wrong the first time. The purpose of this post is to help me get modulo right the next time I need it.

And to realize that all code is error prone, even "trivial" things like this.