Base 3 Base 3 numbers are composed of three different "digits" but they are not the ones you expect. Yes, there is a zero and a one but the other digit is not a two, it is a negative one. These digits correspond to the binary digits as represented in computers with electronic currents. Where binary digits are represented by the presence or absence of a current or voltage, base three extends the analogy to include reversed currents and voltages while keeping the simplicity of only a single absolute level. To emphasize this difference I use special symbols for all three digits instead of reusing the regular digits and letters of the alphabet. For zero I use a dash like this one: "-". for plus one I use the forward slash symbol thus: "/" and unsurprizingly the minus one symbol is then the backslash: "\". The following table shows some small numbers in base three, conventional base10, twos complement 16 bit hexadecimal base 16, twos complement 16 bit octal and twos complement binary base 2. There is also a similarity to the roman number system where negative digits are used to subtract from base 10 and base 5 values. One could generalize this system for any base (larger than base 2) where the digits are distributed between the base and the negative of the base. For instance base 10 could be done with digits from -1 to +8 and it would start to look like a variation of the roman number system. decimal hex octal binary base 3 base base base 8 base 2 10 16 ----\-\ -00010 FFF6 177766 1111111111110110 ----\-- -00009 FFF7 177767 1111111111110111 ----\-/ -00008 FFF8 177770 1111111111111000 ----\/\ -00007 FFF9 177771 1111111111111001 ----\/- -00006 FFFA 177772 1111111111111010 ----\// -00005 FFFB 177773 1111111111111011 -----\\ -00004 FFFC 177774 1111111111111100 -----\- -00003 FFFD 177775 1111111111111101 -----\/ -00002 FFFE 177776 1111111111111110 ------\ -00001 FFFF 177777 1111111111111111 ------- +00000 0000 000000 0000000000000000 ------/ +00001 0001 000001 0000000000000001 -----/\ +00002 0002 000002 0000000000000010 -----/- +00003 0003 000003 0000000000000011 -----// +00004 0004 000004 0000000000000100 ----/\\ +00005 0005 000005 0000000000000101 ----/\- +00006 0006 000006 0000000000000110 ----/\/ +00007 0007 000007 0000000000000111 ----/-\ +00008 0008 000010 0000000000001000 ----/-- +00009 0009 000011 0000000000001001 ----/-/ +00010 000A 000012 0000000000001010 Note the features of these systems: Base 3 has no need for the separate +/- symbols to distinguish negative numbers. The twos compliment bases are particularly confusing for negative number representations. I used twos complement representation for the binary based numbers only because this is the way most computers and C compilers do it. It is also posible, but not shown here, to use a separate sign symbol, as is shown in base 10, with these bases. For an example of separate sign and magnitude used in a computer architecture see "Knuth, The Art of Computer Porgramming, Vol 1". There have also been a few computers in the past which used ones compliment representations for negative numbers. The examples I know of are the CDC 6000/7000 series and the Univac 1100 series. The oddest thing about ones compliment is that there are separate representations for plus zero and minus zero and they are equal but different. Also I have included leading zeros for all examples. They can be omitted but I think it makes things clearer to include them here especially when we are also looking at negative number representations. Arithmetic in base three is almost as easy as binary and it would seem to be almost as easy to automate. So think: One plus one makes three minus one! An addition table would look like this: \ - / ------------ \ | \/ \ - | - | \ - / | / | - / /\ The multiplication table would look something like this: \ - / ------------ \ | / - \ | - | - - - | / | \ - / So similar to the base 2 muliplication table, there are no two digit results requiring extra carries. Here is a C program that produces a superset of the first table: /* base 3 stuff */ #include #include int cvt32n (char *str) { int n = 0; char ch; while ((ch = *str++) != 0) { n *= 3; switch (ch) { case '-': break; case '/': n++; break; case '\\': n--; break; default: fprintf (stderr, "cvt32n: conversion error of `%c'\n", ch); return 0; } } return n; } void cvtn23 (int n, char *str, int slen) { int d; char *digits = "\\-/"; if (slen <= 0) { fprintf (stderr, "cvtn23: string length %d no good\n", slen); exit (EXIT_FAILURE); } str[--slen] = 0; if (n < 0) { digits = "/-\\"; n = (-n); if (n < 0) printf("cvtn23: underflow!\n"); } while (n) { n++; d = n % 3; n = n / 3; if (slen == 0) { fprintf (stderr, "cvtn23: string overflow\n"); exit (EXIT_FAILURE); } str[--slen] = digits[d]; } while (slen) str[--slen] = '-'; /* zero fill */ } void put_bin (int n) { int i; for (i = 15; i >= 0; i--) putchar ((n & (1 << i)) == 0 ? '0' : '1'); } #define SLEN 12 void shownum(int i) { char str[SLEN]; cvtn23 (i, str, SLEN); printf ("%s %+06hd %04hX %06ho ", str, (short) i, (short) i, (short) i); put_bin (i); putchar ('\n'); if (cvt32n (str) != i) { fprintf (stderr, "main: match failed, %d != %d\n", i, cvt32n (str)); exit (EXIT_FAILURE); } } int main () { int i; for (i = -100; i <= 100; i++) { shownum(i); } putchar('\n'); shownum(+0x7ffe); shownum(+0x7fff); shownum(-0x7fff); shownum(-0x7ffe); return EXIT_SUCCESS; } /* end of base 3 stuff */