Thursday, April 16, 2009

Two Unrelated Things

Just finished reading The Swiss Family Robinson. Two main things jumped out at me.

  1. An incredible quantity of animals are killed. It's seriously like every couple of pages they take down a kangaroo, shoot an agouti or chop a snake. After the fact they talk a lot about the "magnificent creature" but beforehand they don't think twice. They don't even know what most of the animals even are and they start shooting. (They also have an unending supply of ammo.)

    The irony of the family often being afraid of "savages" in this context is pretty thick.

    The variety of animals is also pretty astonishing (which is to say fictional). On what island exactly do monkeys, wild hogs, buffalo, kangaroos, lions, boa constrictors and ostriches all coincide?

  2. There are many similarities to Robinson Crusoe. I noticed them at the time but can't think of any now, so I'm left with the obvious statement that they are both shipwrecked on an island.

    Anyway, in the text they mention that they are Swiss (duh) and don't speak English (whoa!). Looking it up afterwards, it turns out that "Swiss Family Robinson" is kind of a misnomer. They aren't named Robinson. In fact, their name is never given, only the 4 sons are addressed by names with the man being the narrator and the wife called "the wife" or "the mother". The real translation of the original title is more like "The Swiss Robinsons" as in "a Swiss version of the Robinson Crusoe".

    Also, especially near the end, there were many similarities with some of the Heinlein juveniles. I think RAH even said he'd "filed the serial numbers off" of SFR a couple times. Knowing the actual plot of the original now, I should reread the juveniles.

The other thing is slide rules. I asked Freecycle for a slide rule and a kind soul gave me 3. All 3 in leather cases, one of them bamboo and new in box. Wow.

One
Two
Three (has 23 scales on it!)

I feel like such a retro-nerd messing around with them, although I can barely do even simple problems. You really get a sense of what a chore basic computation used to be if this slow, error-prone, laborious process was the easy way.

Wednesday, April 1, 2009

Modulo Operator Considered Harmful

The way I think of the modulo operator is as a remainder. 10 mod 3 = 1, because 3 * 3 = 9 and 10 - 9 = 1. But what if one of the operands is negative? What is -10 mod 3?

My naive answer was that this is obvious. -10/3 = -3. -3 * 3 = -9. To get from -9 to -10, you need to add -1. Therefore the remainder is -1. Let's see what C thinks of that:

#include 

int main(void) {
  printf(" 10 mod  3 = %d\n", 10%3);
  printf("-10 mod  3 = %d\n", -10%3);
  printf(" 10 mod -3 = %d\n", 10%-3);
  printf("-10 mod -3 = %d\n", -10%-3);

  return 0;
}

$ gcc -o mod mod.c
$ ./mod
 10 mod  3 = 1
-10 mod  3 = -1
 10 mod -3 = 1
-10 mod -3 = -1
C agrees! And I'm sure Python must follow, right?
#!/usr/bin/env python

print " 10 mod  3 = ", 10 % 3
print "-10 mod  3 = ", -10 % 3
print " 10 mod -3 = ", 10 % -3
print "-10 mod -3 = ", -10 % -3

$ ./mod.py
 10 mod  3 =  1
-10 mod  3 =  2
 10 mod -3 =  -2
-10 mod -3 =  -1
2?!?!

There's a couple ways to look at this. First, what really is the answer of -10/3 in integer division? The "real" answer (seewhatididthere) is -3.333.... When I round that to an integer, do I round "down" meaning "to the left on the number line" or "down" meaning "towards zero"? If I mean the latter, -10/3 = -3. But if I mean the first meaning, then -10/3 = -4. Then 3*-4 = -12 and so the remainder is actually 2. (If you ask Python what -10/3 is, you do in fact get -4, btw.)

Alternatively, I could revert to doing modular arithmetic under it's old name of "clock arithmetic". For 10 mod 3, the face has 3 numbers and I'm going to take 10 steps around it, starting at 0 and moving clockwise. I end up on 1. For -10 mod 3, I'm going to go counterclockwise. I end up on 2.

To me, this second interpretation is better. For one thing, rounding leftwards seems to be as counterintuitive as the original problem. For another, this clock method explains what a 10 % -3 should be. The clock face contains the space of possible answers. Doing mod 3, the answers can only be 0, 1 or 2. Doing mod -3, the answers can only be 0, -1 and -2.

Wikipedia agrees with Python, which seems to leave C out in the cold. Its folk understanding of modulo as remainder is common sense but wrong. And it isn't alone. (Some languages have mod vs rem, with the latter being a remainder. That's a good idea. Naturally FORTRAN has called the two operators mod and modulo. Stay classy, FORTRAN.)

However, it is still true that if you are working only with positive numbers, mod is a remainder. Because of this intuitive understanding, and because of the obvious confusion among language designers, it seems a good idea to me to always frame mod operations in positive space.