Updates:
- 2025-02-19 – Thanks to a comment from William Astle, the term “decimal” number has replaced my incorrect use of “integer.” And per a comment from James Jones, a clarification that all values you input are still stored internally as the same type of numeric floating point – the parsing converts them all to this floating point representation.
Color BASIC had one type of number you could use: decimal. These are the normal numbers we use every day like 1, 50392 or 42.
A=42
PRINT "A IS";A
When Extended Color BASIC was added, the CoCo accepted the following notations for numeric constants: integer, hexadecimal and octal. (Internally, BASIC converts them all to the same numeric representation of a floating point value.)
Getting Started with Extended Color BASIC describes hex and octal as follows:
Extended Color BASIC lets you use both hexadecimal and octal constants.
Hexadecimal numbers are quantities represented in Base 16 notation, composed of the numerals 0 to 9 and the “numerals” A to F. Hexadecimal constants must be in the range 0 to FFFF, corresponding to the decimal range 0 to 65535.
To indicate that a number is an octal constant, precede it with the symbol &H, as shown here:
&HA010 &HFE &HDl &HC &H4000
Octal numbers are quantities represented in Base 8 notation, composed of the numerals 0 to 7. Octal constants must be in the range 0 to 177777. The computer stores them as two-byte integers that correspond to the decimal range 0 to 65535.
To indicate that a number is an octal constant, precede it with the symbol &0 or &, as shown here:
&070 &044 U1777 &7170 &17 &01234
The use of “hex” and octal constants is convenient in programs that reference memory locations and contents. For further information, read a book on machine-language programming.
– Getting Started With Extended Color BASIC (p. 195, 1984 revision)
I most likely learned hexadecimal when I was learning assembly language. Today, I use hex values often in C programming. But octal? I do not think I have ever used it for anything. Have you?
I do believe I have seen it used “in the real world.” In the late 1980s (possibly early 1990s) I had a Kawai K1 synthesizer keyboard. It organized its instrument settings (called “patches” in reference to early synthesizers using “patch cables” to route signals do different processors) into two groups of Internal (onboard storage, uppercase “I” and lowercase “I”) and two groups of External (memory card, uppercase “E” and lowercase “e”). Each section had eight patches.
My first commercial CoCo program was a MIDI Librarian that could read the patches from the synthesizer and save them to disk, or load patches from disk into the keyboard. The patch screen in question looked like this:

You will see that each area had four banks (A-D) and each of those had eight patches (1-8). Uppercase “I” was A(1-8), B(1-8), C(1-8) and D(1-8), and lowercase “i” was the same. This was also the same for the External banks.
Thus, octal. I could have used octal in my program — but I do not know if I even realized this was octal at the time. I’d have to think about how I would have even done that. Maybe something like this:
0 'OCTALIN.BAS (2-15-2025)
10 LINE INPUT "BANK (0-7):";B$
20 LINE INPUT "PATCH(0-7):";P$
30 NM=VAL("&O"+B$+P$)
40 PRINT "THAT IS PATCH #";NM
…though I do not recall how the MIDI messages. It could have just been a user interface thing and internally the patches were still 1-whatever.
But I digress.
Juan Castro posted to the Color Computer e-mail list about a bug in the octal routines:
Octal constant (Ex.: &O14 = 12 decimal)
It accepts 8 as a digit. D’oh. Try “PRINT &O18” in a CoCo 1 or CoCo 2.
Without having a CoCo3 at hand to check I’ll wager it patches that bug. All
it has to do is replace a LBHI with a LBHS.Juan Castro
Enviado do meu Olivetti Programma 101
http://retropolis.com.br
Since an octal value should only be 0-7, a value of 8 is not valid octal.
10 CLS:PRINT"DEC","OCT"
20 FOR A=0 TO 10
30 PRINT A,VAL("&O"+STR$(A))
40 NEXT
This should print 0-7 then error out. Yet…

And is there really no better error than SYNTAX for this type of problem?
And naturally, I had to see what HEX values do. A valid hex digit is 0-9 and A-F, representing 0 to 15. Will it do a syntax error as well if I go past the letter F?

It appears it does not. It seems to bail on the parsing and print them as two variables. Which is a neat trick, since you have to put a space or semicolon between two variables if you want to print them otherwise.
To confirm that is what it is doing, I tried this:

Ah, so it is not treating this as variables “H” and “G”. And I just learned something new (and probably useless).
Something new (and probably useless)…
Integer values are things like 1, 2, or 152032. They are floating point values, so you can also have things like 1.2 or 33.5. Though, not always. Floating point values cannot represent every decimal value accurately, but that’s a story for another article…
Somewhere, someone learned that a decimal (period) by itself would be treated as zero. The fastest way to assign 0 to a variable in Color BASIC is like this:
A=.
Weird, but it works. It seems the parser starts looking for a fractional amount, like “.25” or whatever, so it processes the period and then there is nothing else so the code returns with 0 (the initialization value when the function is called). It is still weird, though.
I found out tonight that the same thing applies to hex. You can do this:
A=&H
…and you get a zero. Try “PRINT &H” to see for yourself.
Of course, I had to try a quick benchmark, sitting in a loop doing something like “Z=.” and another run doing “Z=&H”. 1000 times through with “Z=.” used 140 timer ticks. The “Z=&H” used 154. I guess that is the overhead of parsing two characters instead of one.
But I digress. Again.
I have not looked up what BASIC is doing (see the excellent “BASIC Unravelled” books for the disassembly of the BASIC ROMs), but I suspect the parser starts looking and finds the “&” followed by the “H” and is ready to parse… it then hits an invalid character, so the parsing is over and 0 is there. Then it sees the G, which is not a command so it is treated like a variable.
Using “PRINT” was deceiving. Had I just tried this:
A=&HG
…I would have got what I was expecting:
?SN ERROR
Thanks, Juan, for sharing this. I learned about a bug, and in writing this, discovered another odd thing, which is less odd now that I understand what happened.
Until next time…
I wagered… poorly. Super Extended Color BASIC doesn’t give an airborne intercourse about the octal bug. Given how esoteric it is, I understand them.
I believe we know the Microware guys (I worked with two of them during my days there) used the Basic Unraveled books as reference. It is a pity they did not have time to go through and “fix” all the known bugs that were documented in those books. There is a nasty one in Disk BASIC with the DSKON routine that I ran into when copying all my old floppies to CoCoSDC images ten years ago — crashed the computer HARD. I went to look at what the code was doing in the books and found they had already documented the problem ;-)
Also, Extended BASIC uses different loops to parse octal and hex, since octal digits are nice and consecutive, whereas hex has that whole A to F exception to deal with. I used a simplified version of the octal loop to make my implementation of &B. (Three guesses as to what that does.)
I cheated and saw your reference. But … I am VERY curious how that works with BASIC’s integers. 16-bit value? Basic has problems with 16-bit using AND/OR/etc but works with 15-bit, like signed values I guess.
As one who has spent hours playing with printing binary in Color BASIC, and learning how to bit shift and AND and OR and stuff with them, I am intrigued.
AND, OR, AND NOT demand signed 16-bit integers as input, whereas the &H/&O expressions (and consequantly my &B extension) return UNsigneded integers. That is VERY annoying:
PRINT &H8001 AND &H0007
?FC ERROR
OK
Come the %#&*£ ON!
I seem to recall I tried doing this with hex when I found the 15-bit limit. But I ended up with weird workarounds in my articles.
And have completely forgotten what those where…
I am so gonna blog about this one.
Before you blog, try this on a CoCo 3 for more signed/unsigned fun:
10 ONERR GOTO 50000
20 INPUT “NUMBER”;A
40000 PRINT 3/A
40010 GOTO 20
50000 PRINT ERNO;ERLIN
50010 IF ERLIN<0 THEN PRINT “ACTUALLY”;65536+ERLIN
Wait a sec… if I type 0 to create a div/0 error, the error line you get is negative???
Lines 32768 and later… That’s messed up. I wonder if they mention this in Unraveled. One of the programmers who worked on Super Extended BASIC passed away some years ago, but one of the others is still here local. I may have to track him down ;-)
YES!!! You get a negative line.
– 40,000 is 9c40 in hex
– Loads 9c40 in register
– Jumps to BASIC entry point to return an integer
– BASIC assumes 16-bit value is signed
– Returns -25536
I wrote up a post about this, too, quoting from Super BASIC Unraveled with what they said about this bug.
You wrote that Color Basic has one type of number: integers. That is incorrect. Color Basic (and Extended) only have floating point. I think you meant “decimal” rather than “integer”. Integers are numbers with no fractional part. Those are, of course, valid floating point. But fractional numbers are not valid integers. Thus you cannot use “integer” and “floating point” interchangeably.
Also, in Extended Basic, the & parsing is 16 bit unsigned. The Coco 3 expands that to 24 bits presumably for the extended addresses for use with LPEEK and LPOKE. It does not, however, expand the size of numbers used for AND, OR, or NOT – those remain 16 bit signed integers. HEX$ also is not expanded to handle more than 16 bits.
Good correction! It feels odd to refer to them as “floating point” even though that is what they are internally (I wonder if the BASIC manual ever uses that term?), and “number” didn’t work for me since a HEX value is a number, just in a different form. Decimal is the word I could not think of at the time, which is dumb because “hex to decimal” is a term etched in my long term memory.
Updated.
Be careful. I think the more accurate way to describe what’s happening is
“[version of BASIC] accepts the following notations for numeric constants”. That’s not the same thing as saying that there are multiple internal representations of numbers, as there are in BASIC09 or C. In whatever version of Color BASIC, by the time it is stored or used in a calculation, it WILL be in Color BASIC’s five-byte floating point format, though as you have pointed out, some notations can be converted to the internal format faster than others. Too bad the parser can’t recognize when those notations are used as the address for a PEEK or POKE so that the infamous magic numbers used for addresses could bypass coversion to and then back from floating point.
Noted! I learned from an 8-Bit Show And Tell video that Commodore 64 BASIC had INT types using the % I think. But he showed how they were not faster, which is unfortunate.
Side track:
I might misremember the details, but IIRC 8 and 9 are undefined but not defined to cause an error when used in octal constants in C (or at least it used to be this way)….
If so, still broken since 9 errors. I think I need to find a reason to write something using octal.
Linux/UNIX permissions.