Photograph of the San Francisco Mint Coin Adjusting Room. Tables have assay scales at each station. Coin counting... - NARA - 296577

There are a number of gotchas that trip up new programmers: the difference between declaring a variable and initializing it, the need for semicolons to terminate lines at times, and off-by-one errors, to name a few. All of us in the industry have met genius self-taught programmers who can put together extensive, well-architected applications in their sleep—but all of us have also met self-taught juniors who barely grasp the basics and think that's all they'll ever need. There's a reason degrees and formal training exist, after all.

Today's story happened when Olaf was fresh out of university, working his first non-intern job as a "trainee programmer." The company aimed to improve government health care management: a noble goal, for those who have never had the dubious pleasure of interfacing with healthcare systems. However, it was founded by a doctor with just a smattering of PHP knowledge, all self-taught in his minimal spare time.

Olaf came in with an eye to improving what was there using his knowledge of design patterns. PHP is a simple language to learn, but a hard one to master; much of the PHP software out there uses god objects and mingles code with layout, two big no-nos that are nevertheless taught in most online tutorials. Olaf began separating function from form, creating objects that could be reused to minimize the copy-pasting, and the like, happily bringing order to the chaos he'd been given.

Which is how he found himself in the boss's office, on the wrong end of a dressing-down.

"The other programmers won't understand this!" the boss cried. "It's too complicated. Why are you changing it? It works, just leave it alone!"

Disheartened, Olaf went back to work, checking out a clean copy of the master branch without his changes. Trying to ignore the bad practices, he began working on a bug in the accounting system, a bug marked "high priority" and "urgent" since it dealt with billing. Users would upload CSV files with information about what was spent, and the system would sum the values by category and create billing reports. However, there was a rounding error somewhere in the internals, leading to incorrect sums in a few important edge cases.

Olaf had more training than his coworkers, but no training is exhaustive. He was able to quickly determine that this was a floating point mathematical error. Because decimals aren't represented exactly in binary, the math will be wrong in a few edge cases. He went looking for the right way to handle decimal values in PHP. However, unlike Node or C#, it's actually fairly difficult to include external libraries in PHP, as the language has no built-in support for package management. He was unable to figure out how to add a library that would do the math correctly. Since the software was only doing sums, he advocated for integer mathematics: read in the value, remove the decimal point (so that $10.50 would be represented as 1050), do the math, then add the decimal point back when displaying.

One of the other junior devs loved the idea. The senior developer considered it—but the boss flat-out refused the suggestion. His take? "This isn't a floating-point error. This is because PHP is weakly typed, and it's trying to do summation as strings rather than numbers."

(For those who are curious: PHP does not use the "+" operator to concatinate strings. It uses "." instead. "hello " . "world" results in "hello world".)

The final solution the senior ended up implementing: separate the whole part from the fraction, so that our $10.50 charge becomes $10.00 and $0.50, then sum each portion separately.

Olaf didn't wait around to see what would happen when they discovered that the bug still existed, since they were still treating the cents portion as a floating point number. He found a better job in a better language and never looked back.

[Advertisement] Forget logs. Next time you're struggling to replicate error, crash and performance issues in your apps - Think Raygun! Installs in minutes. Learn more.