Shortcuts and Modulo Calculations28 Oct 2019
The i*OS Shortcuts application has a surprising amount of numerical functions tucked away within its calculation actions. These include not only statistical functions, but also some arithmetic functions familiar to many programmers. One of these is the modulus function. Many of you may have used this in your mathematical studies at school. It is frequently used as the basis for time calculations on 12 and 24 hour clocks. But there’s more than one way to apply a modulus.
Let’s define a generic modulus operation and have it accept two numbers. A value, and a modulus -
mod(value,modulus). To find the result, we would divide the value by the modulus and look at the remainder.
For example, using a modulus of 3, we can see a pattern that forms like so.
mod(1,3) = 1 => 1 / 3 = 0 r 1 mod(2,3) = 2 => 2 / 3 = 0 r 2 mod(3,3) = 0 => 3 / 3 = 0 r 3 mod(4,3) = 1 => 4 / 3 = 1 r 1 mod(5,3) = 2 => 5 / 3 = 1 r 2 mod(6,3) = 0 => 6 / 3 = 1 r 3 mod(7,3) = 1 => 7 / 3 = 2 r 1
Hopefully that’s relatively straight forward to follow. But what if we aren’t dealing with whole number, integer values?
If we take the broadest example above of looking at the remainder, then
mod(5.6,3) = 2.6 => 5.6 / 3 = 1 r 2.6. But, some programming definitions of a modulus go a little further and and say that it is not simply the value divided by the modulus and look at the remainder, but rather the division should be integer division, thus meaning only the integer part of the remainder would be retained. By that definition,
mod(5.6,3) = 2 => INTEGER_PART(5.6 / 3) = 1 r 2.
Some programming languages implement one version of modulus. Other languages implement the other. A few (such as C), implement both - one for integers and one for non-integers (such as C’s
fmod() function for floating point (float) numbers).
The Shortcuts modulus function is based on integer division, but sometimes it can be useful to have a modulus function with a broader operation that retains the factional part. To that end I created a little shortcut to support just that.
The shortcut takes a single list parameter. It expects the first list item to be the value and the second list item to be the modulus. It ignores other list items, and it does not carry out any validation against the values it receives. The modulus is calculated based on the following equation.
value - INTEGER_PART((value / modulus) * modulus)
Since Shortcuts has no integer part operation, that is derived by splitting a number on the decimal point and taking the first item from the resulting list. If you are in a country that uses a different decimal separator such as a comma (“,”), then you would need to modify the shortcut accordingly.
Below are two shortcuts, Modulus, and Modulus Test. Modulus is the shortcut that carries out the calculation shown above. Modulus Test is an example shortcut that calls both Modulus, and performs Shortcuts’ own modulus calculation and shows the results alongside each other. It’s pre-populated with the
mod(5.6,3) example from above and gives the following result:
The Modulus shortcut’s actions break down as follows.
The moral of this story is that even when Shortcuts doesn’t provide the exact function you are looking for, there’s almost always a way to simply build it yourself.