Thursday, April 12, 2007

Negative Ten Kay?

So I have a Java version of the game Bejeweled on my cell phone. It's entertaining, so I play it whenever I have a handful of minutes of nothing else going on and when I'd rather not be thinking too hard. Searching for matches on a grid of gems is a great way to derail my train(s) of thought. It's especially nice because my phone will suspend the JVM when you close the lid (it's a flip phone), allowing the game to be resumed at a later point.

I've scored pretty high on the game, and with Tracy playing whenever I let her, we've managed to rack up some impressive scores. I got 31k on an untimed game, before running out of moves. She scored some 48k on a timed game that I took over, pushing that score to some 55k before running out of time.

So, having scored some 52k, what do you think I saw when I fired up a fresh game of Bejeweled this morning?

If you guessed -10k, then you're right on! Props for figuring out my weird title.

"Okay, so how in the world did 52k become -10k?" you ask.

Actually, it's pretty simple. The largest number you can store in 16 bits is 65535 - that's 2^16 - 1. If you want negative numbers, you have to halve that, and get 32767. To be precise, in 16 bits, you can store [-32768, 32767]. All well and good.

The trick is, in 2s-complement arithmetic (which is what the adders in modern microprocessors use), if you have the largest positive number and add one to it, instead of the data value saturating, it wraps around. So 32767 + 1 = -32768, not 32768. Convenient at the logic level; horrible in terms of intuitive results.

So what's a programmer to do? Well, you can use a larger integer - say, a 32-bit integer, rather than a 16-bit integer. That raises the maximum signed value from 32767 to some 2 billion: 2147483647. So why didn't they do that? Well, likely the phone doesn't have support for 32-bit integers: it may very well be a 16-bit machine. So instead they should have used unsigned numbers, thus making the max score 65535, and checked for overflow on every addition, saturating the score to 65535. And probably ending the game with a big banner saying: "You win because we were too lazy to emulate 32-bit arithmetic in software on this platform!"

But here's the real gripe. In the game, I saw that my score was topping 50k. Clearly, at that point, they were using the unsigned (non-negative) 16-bit number - the one that would let them store values up to 65535. Now why on earth would they write that number out (or read it back in) as a 16-bit signed number? What kind of moron does that? And what kind of complete idiot writes a game in which it is so easy to score over 35k and doesn't consider whether or not the storage he's allocated for the score is adequate? Obviously the type of moron who's writing cell-phone games for a living.

Ridiculous.

"Type theory. Do you have it? Can I have it? Reward!"

No comments: