From the Stupid PHP Tricks files: rounding numbers and creeping inaccuracy

This morning as I walked to the studio I was doing what geeks do best: pondering a slightly esoteric mathematical quandary.

Glass Half Full by S_novaIngraining the American spirit of optimism at a young age, and under dubious circumstances, our schools always taught rounding numbers in a peculiar way. You always round your decimal values to the nearest integer. That part makes sense. But what if the decimal is .5 — exactly half? In my education, at least until late in high school (or was it college?), we were always taught to round up! The glass is half full. Optimism.

Eventually — far later than it should have been, I think — the concept was introduced that always rounding .5 up is not really that accurate, statistically speaking. It might be nice in the case of a single number to be an optimist and think a solid half is good as a whole, but in aggregate this thinking introduces a problem.

If you have a whole lot of numbers, and you’re always rounding your halves up, eventually your totals are going to be grossly inaccurate.

Of course, the same would happen if you were ever the pessimist and always rounded down.

The solution, I later learned, was to round halves up or down, depending upon the integer value that precedes them. Which way you go doesn’t really matter, as long as you’re consistent, but as it happens, I learned it as such: if the integer is odd, round up; if it is even, round down.

In my work, I write a lot of PHP code. Most of it is of the extremely practical variety; I’m building websites for clients, after all. But every once in a while I like to indulge my coding abilities in a bit of frivolous experimentation, and so today I produced a little PHP script that generates 10,000 random numbers between 1 and 100, with one decimal place, and then it shows the actual sum and average of those numbers, along with what you get as the sum and average if you go through all 10,000 numbers and round them to whole integers by the various methods described above. Try it for yourself!

Any time the rounded average is different from the “precise” (and I use that term somewhat loosely) average, it is displayed in red. Interestingly, and not at all surprisingly, when you always round halves in one direction or the other, at least one of those directions will (almost) always yield an incorrect average. Yet if you use the “even or odd” methods, both of those methods will almost always yield a correct average.

It’s all about the aggregate.

You can’t specialize in everything

It’s been one of those weeks that a freelancer dreads. Lots of fires to put out. You’re trying to swim upstream (as always) but instead you’re treading water in a rapids. Without a team of coworkers to depend on, when a problem arises, there’s no one to pass the buck to, or at least to, uh, share it with.

The problems haven’t really been that bad. Just a few bugs to squash, a few scripts to optimize, a few clients to reassure. But when you feel like you have to be the expert at whatever you do, this kind of week can be a source of anxiety.

It doesn’t help when your main lifeline to the tech world is the expert blogs you follow. Read a few articles on A List Apart and you’ll feel both inspired and a little despondent. There are so many incredibly talented, creative people out there doing amazing things. So why am I banging my head against the wall trying to figure out why all of my form fields suddenly disappeared in IE6? (Turns out it was the position: relative on the #main element, easily fixed by overriding it with position: static in the IE6-specific CSS file I wish I didn’t have to create.)

The point is, as a freelancer, at least one who aspires to be good, if not great, at what you do, you are your own harshest critic and worst enemy. There’s no way any of my clients would ever beat me up the way I beat up myself. I don’t think I’ve ever even had one detectably angry with me. But I am constantly getting frustrated with myself for not being on top of every single technology I put my hands on, and I’m inclined to treat every bug as a personal failure.

The sad fact is, it’s impossible. You can’t specialize in everything. It’s right there in the word. Specialize. As a freelancer, you have to pick a few things to focus on as your greatest strengths, while becoming as well-rounded as you can. But there’s always someone out there who knows more about CSS3 or HTML5 or PHP or jQuery or Whatchamacallit than you do. The great thing about being a freelancer in the age of the Internet, especially if you work on the Internet, is that a lot of those superstar über-geniuses are willing to share that knowledge with you for free. All you have to do is search for it.

The biggest danger in following the superstars of your chosen field, though, is idol worship. You get to know so many facets of their work and their personalities (especially if you follow them on Twitter), that you may be tempted to think you know them personally. You might even have a brief exchange with them about baseball. But that doesn’t mean you know them or know what their lives are really like.

We all make sacrifices to live the lives we choose. It’s inherent in the finite nature of human existence. Chances are, I’ll never be a web development “rock star,” because I’ve made choices that took me on another path. I wanted to be able to work on my terms, and fit my career in as one aspect of my life. I’m not logging the kind of hours I’d need to in order to get rich doing work for hire, or building the next great social networking site. But I have time to spend with my kids and SLP (though probably still not as much as would be ideal). I can make music. I can try to set the world record on my Asteroids cocktail table. (OK, that’ll never happen, but it’s 2 feet from my desk in my home office, if I ever decide to get serious.) I can take an afternoon off to take my son to see Toy Story 3 or head down to Target Field for a Twins game or write on my coffee blog or get some fish tacos at Sea Salt.

Or, I can spend half the morning beating myself up because I’m not Jeffrey Zeldman. But, who is? (OK, he is. But that’s it.)

The point is, I’m me. I’m damn good at what I do, but I can’t do everything. And that’s OK.

Ow, my brain!

Apollo 11 astronautI write code for a living. But we web developers have it easy. Server-side scripting languages like PHP may look alien at first, but they’re pretty easy to pick up and intuitive enough that you can really get going pretty fast, and once you’re familiar with the basic principles, it’s not hard to look at a block of code and figure out what it does.

But programming in the old days was a much finer and darker art. System resources were scarce, and everything had to be as efficient as possible — on the computer hardware, at least. A lot more of the “processing” had to happen inside the brains of the programmers before any of the code was even written. Looking at this kind of old code fries my brain.

The most notorious example of old-school assembler code I’ve encountered is the language used to program the Atari 2600. That’s something I’ve never been willing to touch, myself. And it’s for something trivial — video games. But here’s something that really freaks me out: the original source code from Apollo 11. This code is every bit as inscrutable — or more — and it was mission critical: the lives of three astronauts, over 200,000 miles from Earth depended on it working flawlessly.

Well, they made it back, so I guess it worked. But looking at the code, I have no idea how. Here’s an excerpt:

GUILDEN		EXTEND			# IS UN-AUTO-THROTTLE DISCRETE PRESENT?
# STERN					# RSB 2009: Not originally a comment.
  		READ CHAN30
		MASK	BIT5
  		CCS	A
  		TCF	STARTP67	# YES
P67NOW?		TC	CHECKMM		# NO:  ARE WE IN P67 NOW?
		DEC	67
		TCF	STABL?		# NO
STARTP66	TC	FASTCHNG	# YES
		TC	NEWMODEX
DEC66		DEC	66
		EXTEND
		DCA	HDOTDISP	# SET DESIRED ALTITUDE RATE = CURRENT
		DXCH	VDGVERT		# 	ALTITUDE RATE.
STRTP66A	TC	INTPRET
		SLOAD	PUSH
			PBIASZ
		SLOAD	PUSH
			PBIASY
		SLOAD	VDEF
			PBIASX
		VXSC	SET
			BIASFACT
			RODFLAG
		STOVL	VBIAS
			TEMX
		VCOMP
		STOVL	OLDPIPAX
			ZEROVECS
		STODL	DELVROD
			RODSCALE
		STODL	RODSCAL1
			PIPTIME
		STORE	LASTTPIP
		EXIT
		CAF	ZERO
		TS	FCOLD
		TS	FWEIGHT
		TS	FWEIGHT +1
VRTSTART	TS	WCHVERT

Source: Daring Fireball (of course).