Counting to 69420

andrew@paon.wtf

A long walk

I’ve had this idea for a long time: I should wake up one morning, get dressed, walk out the door and just keep walking until I can’t anymore.

Last Monday, May 29, 2023, I did it. I walked out of the house at 8am with no plan but to walk for a really long time. The results are on Strava:

The plan

When you’re addicted to Strava kudos like I am, you spend time during your activity figuring out how to make the activity appear as amusing as possible. To this end, I decided that I should end the activity on exactly 69420 steps. There’s just something really funny about overcommitting to a dumb joke.

I knew it would be tricky to get to an exact step count, because the counter on my watch doesn’t update on each step. But there was an unexpected challenge lying ahead.

Disaster

After walking for almost 11 hours and taking roughly 65000 steps, I looked at my watch and saw something terrible:

photo of the watch face

The count had dropped back down to just over 200. Any idea what happened? After a couple minutes, I had a guess.

Representing integers

First, a quick diversion to talk about how numbers are represented in binary. If we use 2 bits, we can represent 4 different values. Assuming those values are non-negative integers, we get:

00 => 0
01 => 1
10 => 2
11 => 3

If we have 3 bits, we can represent 8 different values, or the numbers 0-7

000 => 0
001 => 1
010 => 2
011 => 3
100 => 4
101 => 5
110 => 6
111 => 7

The pattern is: n bits can represent 2n different values. If we are using these bits to represent non-negative integers, the lowest value is 0 and the highest is 2n-1.

The solution

So how is this related to my problem? It occurred to me that 65000 is pretty close to a meaningful power of 2: 216 = 65536 (these are the kinds of useful facts you accidentally memorize in a lifetime of programming.)

If Garmin was using a 16-bit integer internally to represent my step count, it would be able to represent numbers from 0 to 65535. If we add 1 to that maximum value, we end up back at 0. This means, in order to know when I reach 69420 steps I would need to look for 69420 - (216 - 1) = 3885 on the watch display.

I walked my last three thousand steps and managed to pause it right at 3885. When the activity appeared on my watch, it read 69420 steps. Success!

Conclusion

There is one mystery remaining: why did the uploaded activity list 69420 steps instead of 3885?

My theory is that there are two steps variables in the watch software:

  1. a 16-bit unsigned integer used for display
  2. a canonical steps count that uses a larger integer type

Every time the display updates, the canonical steps count is copied (and possibly truncated) into the display variable. And when the activity is saved, it uses the larger canonical steps count.