Category Archives: Technology

My Knuth Check

Twenty years ago today, I got a Knuth Check. Knuth dated it October 14, 2001, and I received it in the mail in early November that year, I think.

The Check. Details blurred for security, of course.

I’d heard, of course, about Knuth Checks, but I didn’t really know as much about them then as I do today. I was a kid a few years out of college, just trying to eke out a living building software; and when I found a mistake in an algorithm in his book, I intended to write a note in a short e-mail to Dr. Knuth, but I found out he was (wisely) avoiding the medium, so I sent him a letter. And a few months later, I got back a check.

It’s sat in a frame on my desk for twenty years, singularly my proudest professional accomplishment. I’ve shipped tons of software, I’ve made and discovered amazing things, I’ve won other awards — but nothing holds a candle to having a Knuth Check with your name on it.

(More accurately, the original is in my safe-deposit box at the bank, and a copy has sat in a frame for twenty years, because I’m not leaving something this valuable out on my desk! 😃)

So here’s the story:

The Art of Computer Programming, Volume 1, has an algorithm on page 26 that describes an efficient solution for calculating a fractional logarithm in binary, using pure integer math.  The algorithm in question derives from one first published in 1624 by Henry Briggs.  At the bottom of page 26 in the 3rd Edition, the book mentions that Richard Feynman (yes, that Feynman) determined an efficient inverse algorithm for calculating a fractional exponent in binary, and it proposes to the reader to solve it as problem #28.

As is typical of all of Knuth’s “problems for the reader,” he includes the answer in the rather large appendix that comprises the last 150 pages of the book.  The solution to problem #28 can be found at the bottom of page 470, and, unfortunately, it is not the same algorithm that Feynman discovered:  It has a critical error in the first step:

E1. [Initialize.] If 1 – ϵ is the largest possible value of x, set y ← (nearest approximation to b1-ϵ), x ← 1 – ϵ, k ← 1. (The quantity yb-x will remain approximately constant in the following steps.)

TAoCP, V1, 3rd ed., pp. 470

That has a rather unfortunate error in it: x ← 1 – ϵ is potentially a meaningful expression in that context, but it’s wrong, and it will calculate not the correct exponent but garbage data, with, as I recall, mostly zero bits and a few semi-randomly-distributed one bits.

The correct expression is x ← 1 – x.  It’s possible the other form was a typographical error on Knuth’s part, but it’s not in the same category as a simple omission or spelling error, since if you follow the mathematics as written, you will simply get garbage, and not get a valid fractional exponent.

(I struggled for a few days with the original: It was Knuth; surely I’d been the one to make the mistake in my code, not the good Doctor in his! But ultimately when I began to experiment with the broken algorithm, the answer became obvious.)

So I wrote Knuth a letter in the spring of 2001 saying that I thought that was wrong as published, since it generated garbage output, and I included that I thought that x ← 1 – x was actually the correct form, since it appeared to be correct. And he sent me back a rather nice letter and a check for $2.56 for having found an error.

(I had also suggested that the inherent parallel execution implied by the commas in step E2 appeared to be wrong, that sequential execution appeared to be needed there; Knuth chastised me in the letter that no, parallel execution was in fact intended.  But I still got an error check for a broken algorithm!)

Interestingly, I didn’t get my check by just searching for errors, like many people have:  I was trying to build something; I encountered that error merely by remembering that the books contained an answer to the problem I was facing.  But it seems that not many people build things by literally reading the textbook and doing exactly what it says; and apparently, nobody had implemented Feynman’s exponentiation algorithm from the book after it appeared in the 3rd Edition in 1997. [ed. note: I checked, and Knuth added it to the 3rd Ed. in April 1995; my error can be seen in his addenda.]

That said, an entertaining question to posit:  Why the heck was I trying to implement fractional logarithms and exponents in the first place?

The answer was that it was 2001, and Windows 98 and ’486 PCs were still pretty common, and you couldn’t assume a computer supported floating-point math.  And I needed to calculate powers:  As simple as xy, just like on your calculator, and it was even constrained: In my case, x was always an integer, and y was always a number between 1 and 2. But I didn’t have guaranteed floating-point hardware available so I could just write pow(x, y). So I improvised:  I used the Briggs and Feynman methods to calculate the logarithm and the exponent in pure integer math, so that I could implement calculation of a power as exp(y * log x) instead, and effectively use multiplication — which the hardware supported — to produce a power (which it definitely didn’t).

Today, of course, I’d write pow(x, y), just like you would. But when you’re stuck on super-limited hardware, you have to be a bit more clever.

(For what it’s worth, you can see the code live, in action, if you have a copy of SpaceMonger 2 or 3; just go into the Settings, and turn up the “Exaggeration” slider: Every file’s size will be raised to the power you choose, using exactly this math!)

Feynman, of course, derived that algorithm for exactly the same reason I needed it:  They were using mechanical adding machines during WWII as part of the Manhattan Project, and those machines didn’t do powers.  But the relativistic math for the atomic bomb needed lots of powers; so he derived the exponent algorithm as the converse to the logarithm algorithm, so that they were able to just use addition, subtraction, and multiplication, which the adding machines could do, to still efficiently calculate powers, which the machines couldn’t.

So that’s my Knuth Check story. It’s unlikely I’ll ever earn another; I certainly haven’t in the last twenty years! I still haven’t even finished reading Volume 4A yet, and I’m far too busy to randomly pore over the other tomes again just in search of a mistake. But I still managed to earn a prize that’s among the most coveted in this field, and twenty years later, I’m still happy to have done it even once.

Leave a Comment

Filed under Programming, Technology

Reminder: .NET Dictionary isn’t ordered

I’ve had to say this several times over the years, so I thought I’d repeat it in a place where I can just make a link to it: The Dictionary<K,V> class in .NET does not store your data in order.

When you .Add() or .Remove() items from a dictionary, they get stored in whatever order the dictionary finds is most efficient. It just so happens that as long as you never .Remove() an item, the underlying data structure ends up with the items in order when you enumerate them, but this is not guaranteed.

Here’s an example program to demonstrate that it doesn’t work the way you probably expect:

public static void Main()
{
    Dictionary<string, string> fruits = new Dictionary<string, string>
    {
        { "A", "Apple" },
        { "B", "Banana" },
        { "C", "Cherry"},
        { "D", "Durian" },
        { "E", "Elderberry" },
        { "F", "Fig" },
    };
    
    Console.WriteLine("Fruits:");
    foreach (KeyValuePair<string, string> fruit in fruits)
    {
        Console.WriteLine($"{fruit.Key} -> {fruit.Value}");
    }
    
    fruits.Remove("D");
    
    fruits.Add("G", "Grape");

    Console.WriteLine("\r\nFruits:");
    foreach (KeyValuePair<string, string> fruit in fruits)
    {
        Console.WriteLine($"{fruit.Key} -> {fruit.Value}");
    }
}

You might think reading this that the first output would be in order of [A, B, C, D, E, F], and the second would go [A, B, C, E, F, G]. But that’s not the output that’s produced:

Fruits:
A -> Apple
B -> Banana
C -> Cherry
D -> Durian
E -> Elderberry
F -> Fig

Fruits:
A -> Apple
B -> Banana
C -> Cherry
G -> Grape
E -> Elderberry
F -> Fig

The new entry gets slotted in where the last one was removed, which is exactly the behavior you’d expect if you had read the underlying code, but it’s very different than what you’d expect if you just assumed everything will always have insertion order.

Moral of the story: If you need dictionary data to be ordered, don’t assume it’s ordered — explicitly order it!

  • If you need things to be in insertion order, keep them in a list.
  • If you need things to be ordered by key, consider a SortedDictionary<K,V> instead.
  • If you only need things sometimes to be ordered by key, use Linq: dictionary.OrderBy(pair => pair.Key)

Comments Off on Reminder: .NET Dictionary isn’t ordered

Filed under Programming

JS thought of the day

In the old days if you encountered a badly-coded website, you could often fix it with tools like TamperMonkey: Hack a little JavaScript, and you could fix the worst of the site’s abuses, or even make it nicer and add features the original developers didn’t (or couldn’t) add. Everything was fairly open, so you could just drop new script on the page, and even substitute out functions if you had a better implementation.

We now live in a reality driven by WebPack, where every website’s JavaScript is packed, minified, bundled, and, importantly, smashed together inside a closure, making all of its innards and mechanics hidden and encapsulated, hidden even from its own code.

That’s great for application stability, if you have good developers. But it also means that the app you get is the app you get: Every bug, every design flaw, and every misfeature is hidden away inside that bundled ball — which means that no matter how bad it is, you can’t fix somebody else’s broken website anymore.

Comments Off on JS thought of the day

Filed under Programming

React Considered Harmful

This is one of those strange posts I never thought I’d write.

For the record, I love ReactJS. The principle of being able to build an entire website using forward-only data flow was sheer raw brilliance, and was a fundamental architectural shift in how website UIs work.

But —

Continue reading

Comments Off on React Considered Harmful

Filed under Programming

SpaceMonger Redux, Part 2: The Project

I’ve wanted for a long time to describe in detail how SpaceMonger works. It’s been more than twenty years since I wrote SM 1.0, and there were a lot of innovations in SM 2.1 that I still really haven’t seen appear in any discussions elsewhere: I worked really hard to make SM fast and as smooth, even on the ridiculously limited computer hardware of the early 2000s.

Part of the work in making SM 2.1 was finding and using unusual algorithms that aren’t given much attention outside computer science literature — and part of that work was discovering and inventing new algorithms that, to the best of my knowledge, haven’t been published anywhere since. In this series of articles, I aim to fix that fact: It’s bothered me a lot that I’ve been hoarding some knowledge over the years, and it’s well past time that I share it.

Continue reading

Comments Off on SpaceMonger Redux, Part 2: The Project

Filed under Programming

SpaceMonger Treemapping Redux

I was asked recently (for the 97,000th time), “I loved the treemap layout algorithm in SpaceMonger. I’d like to implement something similar. How did that algorithm work?”

I’ve been meaning to write a few articles on this for a while now, so here we go with the first one: How did SpaceMonger 1.x’s treemapping work?

Continue reading

Comments Off on SpaceMonger Treemapping Redux

Filed under Programming, Uncategorized

I’m still doing things

It’s been a while.

The credulity of my tagline — where I’m still writing but you’re not reading — seems to be a bit stretched lately, as it’s been months since I last posted anything about anything.  That’s not for a lack of interesting things to write about, but mostly for a lack of time in which to do it:  I most often think of things to say while driving to or from work, or while lying in bed at night having spent my evening feeding and cleaning up after small children, and neither scenario is especially conducive to posting on one’s blog.  Even when I do get a little private time, I tend to spend it working on Smile, rather than posting here about Smile, which doesn’t especially help with anybody else knowing what’s going on with it.

So let’s talk about Smile.

Continue reading

1 Comment

Filed under Smile, Technology

A Smile Posting!

Okay, so it’s apparently been forever since I talked here about Smile.  Which is sad, because I think hard about it every day, and I work on its code multiple times a week.

So here goes with a big status update.

Continue reading

Comments Off on A Smile Posting!

Filed under Smile

UI Tip: The User Is Busy

I’m passionate about user-interfaces. And so I thought it would be worthwhile to expand on a UI discussion I was in on Slack today.

You should never call a user dumb. I prefer to use the phrase busy, one of the great suggestions from Al Cooper’s About Face. I prefer that phrase because nearly all users are not dumb: The bell curve and a whole heap of population statistics say otherwise.

The real issue is that most users are just too busy and too harried to really think about your software or to spend any time with it or to spend any time learning it. They only use it because they have to use it, most likely because some manager at their company bought it and said, “This is your new [X] now.”

Continue reading

Comments Off on UI Tip: The User Is Busy

Filed under UX

Windows 10

Microsoft really screwed the pooch with Windows 10.

Over the past six months, I’ve had the opportunity to both install 10 and use it on quite a lot of machines.  It’s better than Windows 8, but that’s a lot like saying two broken legs are better than cancer:  You really wish there was another option.

So, look, lest you all think I’m just a hater, I have intentionally upgraded my devices to Windows 10, and stuck with it for long enough to get a real feel for it.  I want to be using the new operating system.  It’s just simply not ready for prime time.

Continue reading

Comments Off on Windows 10

Filed under Technology