## Saturday, August 15, 2009

### adventures in ignorance: modulo operator

Recently on the Perl Beginners mailing list I saw a new user having difficulty understanding the documentation for `||=`. My first reaction was "hey, it is spelled out in straight forward English, `||=` is like `+=` but using `||` instead of `+`, go look up `||` and you there you are." Then I starting thinking about it. As a reference, `perlop` is less than optimal. Many of the operators are discussed tangentially (like ||=) and many others are never mentioned (like the file test operators, which I know are documented in `perlfunc`, but they look like operators to me). This has inspired me to write `perlopref`. I haven't socialized this anywhere but the Perl Beginners mailing list and here because I want to make sure the idea is viable first. So far it seems to be working for me, and I am learning a lot of the nooks and crannies I had been able to ignore in the past.

One of these nooks (or is it a cranny?) is the modulo operator (`%`), or more specifically what happens with negative numbers. I had never bother to consider how negative numbers would affect modulo. I found the text in perlop to be very opaque. Every time I tried to read it I found my eyes slipping down the page trying to get away, and I know what modulo does. I don't know if it is me, or the text, but I can't imagine trying to understand what the text was saying if I didn't already know what it did. Here is the part that covers modulo in my first draft of `perlopref.pod` (the pod is available here)

X % Y
Description

This is the modulo operator. It computes the remainder of X divided by Y. The remainder is affect by the type of the numbers and whether they are positive or negative.

Given integer operands X and Y: If Y is positive, then `X % Y` is X minus the largest multiple of Y less than or equal to X. If Y is negative, then `X % Y` is X minus the smallest multiple of Y that is not less than X (i.e. the result will be less than or equal to zero). To illustrate this, here are the results of modding `-9` through `9` with 4:
`when X is     -9 -8 -7 -6 -5 -4 -3 -2 -1  0  1  2  3  4  5  6  7  8  9the result is  3  0  1  2  3  0  1  2  3  0  1  2  3  0  1  2  3  0  1`
And here is `-9` through `9` modded with `-4`:
`when X is     -9 -8 -7 -6 -5 -4 -3 -2 -1  0  1  2  3  4  5  6  7  8  9the result is -1  0 -3 -2 -1  0 -3 -2 -1  0 -3 -2 -1  0 -3 -2 -1  0 -3`
From this we can see a positive Y constrains X to a range from `0` to `(Y - 1)` that wraps around and a negative Y constrains X to a range from `(Y + 1)` to `0`.

When Y is a floating point number whose absolute value is in the range of `0` to `(UV_MAX + 1)` (where UV_MAX is the maximum of the unsigned integer type) X and Y are truncated to integers. If the absolute value of Y is larger than `(UV_MAX + 1)` then the formula `(X - I * Y)` (where I is a certain integer that makes the result have the same sign as Y). For example, on 32-bit systems `4.5 % (2 ** 32 - 1)` is `4`, but `4.5 % 2 ** 32` is `4.5`.

Note: when the `integer` pragma is in scope `%` gives you direct access to the modulo operator as implemented by your C compiler. This operator is not as well defined for negative operands, but it will execute faster.

Example
`my \$odd = \$x % 2; #\$odd is 1 when \$x is odd and 0 when \$x is evenmy \$hour = (\$hour + 1) % 24; # 23 (11pm) plus 1 hour is 0 (12am).`

#### 3 comments:

1. This is very nice. What I like most is your remark about those stupid file test operators that I am never able to find in the documentation. Although I usually use perldoc from the commmand line, if I have to look up the file test operators, I have to rely on that bookmark.

2. Yeah, typing perldoc -f -X is not exactly intuitive. I am also thinking about modifying perldoc to take another switch to let you look up operators on their own like the -f switch does for functions: perldoc -O "X % Y". But I need to finish the POD before I start thinking too seriously about that. I current have 27 of the 74 operators in perlop's chart of operator precedence done. That number does not include filetest operators (27 more) and anything else I might find that should be in it (like the quote-like operators). If you want to look at what is done so far (or help by claiming a few operators), I have created a GitHub repository: perlopref.

3. It sounds good to me. I probably was programming perl for over 5 years before I stopped doing a man on 'perlop' before 'perlfunc' when looking for the file test operators. For part of that time, I just did a man on zshmisc, because most of the operators were roughly the same as zsh's, and I knew where those were.

Some limited HTML markup is allowed by blogger: strong, b, i, and a. You may also use em, but I have repurposed it through the magic of CSS to be behave very much like <tt><code></code></tt>.