Representing numbers presents many choices. Teedy Deigh counts the ways.
A programmer is nothing without numbers. And there are so many to choose from! Unfortunately, because of the taxation of representation – integers are bitly stunted to ints and floating-point numbers aren’t real – a programmer has fewer to play with than the average (and sometimes mean) mathematician. This can leave some programmers with an inferiority complex, a problem that is both real and imaginary.
Many mathematicians, however, fear both numbers and meaningful variable names. Programmers, on the other hand, revel in – and overflow – different number representations and bases and delight in the full range of identifiers from the unidentifiable to the VeryExplicitlyMeaningfulThisIsAnAdjectivalPhraseServingAsANominal.
To make life a little more interesting and less inferior, here is a brief list of some bases you should know and employ, presented in hash order:
binary is the base line of code, its very bits: on or off, 1 or 0, yes or no, true or false, fact or alternative fact, to be or not to be, do or do not... there is no try – which goes some way to explaining the popularity of Boolean and Booleanish return values in languages without exception handling, leaving readers with the frisson of uncertainty as to whether 0 means success or failure or quite possibly both.
unary is the fundamental counting system of the universe – a million things is represented by a million things, not seven. Getting your hands on this original digital base is easy: one finger is 1, two fingers is 2 – or 11 1 – three fingers is three – or 111 1 – and so on. The simplicity of this system means that you can be free and easy with your choice of digit, i.e., instead of 1 you can use a pebble, a dash or a solipsistic I. It is also easy to generate in code. For an integer n , the following Python expression is a unary converter:
('I' * n)
You can also give it a bash with
printf %"$n"s | tr ' ' 'I'
ternary
does not simply give us the operator of champions – Elvis is not dead... albeit conditionally – it gives us the three-valued logic of comparisons (-1, 0, +1) and uncertainty: SQL’s
TRUE
,
FALSE
and
NULL
; JavaScript’s
"false"
,
false
and NaN; the it-compiles-but-does-it-work yes/no/maybe.
octal
is the base of the Unix demigods. It has been said that it is better to
fseek
forgiveness than to ask permission, which perhaps explains why octal has been progressively marginalised and relegated to file permissions. New Testament C makes it clear that 8 and 9 are not octal digits, whereas old testament C was somewhat looser and more permissive, anticipating Postel’s law (‘Be liberal in what you accept, and conservative in what you send’) and the Liskov Substitution Principle (LSP, which is not to be mixed up with LSD... although that might explain a few things).
nonary is of surprisingly little use to the programmer, except as an off-by-one overflow for octal. It should be noted that 9 is not a nonary digit. It is listed here simply to highlight the common existential confusion between nonary and...
nunnery , which is a number base that highlights deep questions of existence and non-existence in black and white (and wimples). For example, Hamlet’s to-be-or-not-to-be binary quandary takes place in what is known as the nunnery scene. When it comes to representation of nunnery in code we can turn to Nietzsche for implementation inspiration:
If you gaze long into a
void
, the
void
also gazes into you.
decimal is widely understood and in common use among the general population. It is, therefore, of little interest to the programmer.
hexadecimal is how binary wants to be organised and what octal always wanted to be. Use it everywhere, especially when people are expecting decimal.
duodecimal is often touted as a geeky base which should be used in place of decimal. While this is certainly a point in its favour, it’s a claim that doesn’t meet all of its challenges. For example, base 12 is often touted as being better than decimal because 12 has so many divisors – 1, 2, 3, 4, 6, 12 – which means that in the interval 1..12 half of the integers are divisors. 50%? Not bad. Applying the same analysis to binary – 1, 2 – and unary – 1 – however, gives 100% coverage.
Advocates of legacy measurement systems also advocate duodecimal, noting that uncia , the Latin for twelfth part, gives us inch and ounce . Hence, 12 inches per FPS foot, 16 ounces to an avoidupois pound (a hexadecimal wannabe if ever I saw one) and 20 fluid ounces to an imperial pint (easily expressed in a bi-denary system). Clearly, there are some issues of legacy and implementation to be worked out before they’re ready to present this one.
dewey decimal is an arcane numerological system for organising libraries. Forget packages and namespaces – or, more popularly, spaghetti inheritance and obfuscators – the priesthood of librarians has developed a far more obscure approach to structuring and deploying information systems.
There is also a parable of number systems, as told in Silent Running , which begins with ternary (Huey, Dewey and Louie), is reduced to binary (Huey and Dewey), then finally unary (Dewey).
bi-quinary
is a much overlooked and classic digital system. Bi-quinary coded decimal is based on pairs of fives - hold out your hands - and can be found in proper abacus systems and early computers, such as the Colossus. It has been said that it is awkward to use and difficult to convert to and from. On the other hand, given a prior unary conversion, it has also been
sed
:
s/IIIII/V/g s/IIII/IV/ s/VV/X/g s/VIV/IX/ s/XXXXX/L/g s/XXXX/XL/ s/LL/C/g s/LXL/XC/ s/CCCCC/D/g s/CCCC/CD/ s/DD/M/g s/DCD/CM/