# How did FOCAL convert strings to a number?

Reading over the manuals for FOCAL-69 and -71, as well as U/W-FOCAL, I realize there is one bit of the workings that I can't find an explanation for.

FOCAL did not have string variables, so to allow "string like" handling the user could type in string values at ASK instructions and it converted that to a number. It also allowed you to type in "string like constants" with a leading zero. So one might...

``````1.10 ASK "TYPE YES OR NO",A
1.20 IF (A-0YES) 2.0,3.0,2.0
``````

The user's input is converted to a numeric value in A, and then that is compared to a similar conversion of the constant, and then it jumps to group 3 if they did type YES and 2 otherwise.

Ok great, but precisely how does it do this conversion? I can't seem to find any description of what it does. I found a FOCAL interpreter in GitHub, but it appears to use the "letter value", A=1, M=13 etc., and I'm not at all sure that's what they used on the PDP-8. All that is mentioned in the docs is that an E will be interpreted as an exponent, such that "YES" will be interpreted as "Y to the exponent S".

Does anyone know how this worked? I suspect the answer is in this post, but I can't be sure which one of the options it might have used.

UPDATE: looking at the 6-bit codes, A is indeed 1 etc, so it appears it is using them? Is it likely they just stuffed them two-to-a-word until it hit the limit of a FP variable?

UPDATE 2: I've posted the working code here.

• Would think so. With machines using 6 bit characters and 4 bit decimals that kind of "conversion" was quite common - including IBM before /360. Commented Apr 5, 2023 at 14:41

While the PDP-8 indeed frequently used 6-bit characters packed into a word, the way FOCAL handled "alphanumeric numbers" seemes to be different.

You can easily run a PDP8 FOCAL in simh, and you can use the `TYPE` command with exponential formatting to see what happens on conversion:

``````*TYPE %
*TYPE 0A,!
= 0.100000E+01
*TYPE 0AB,!
= 0.120000E+02
*TYPE 0ABC,!
= 0.123000E+03
*TYPE 0ABCD,!
= 0.123400E+04
*TYPE 0ABCDA,!
= 0.123410E+05
*TYPE 0ABCDAB,!
= 0.123412E+06
*TYPE 0ABCDABC,!
= 0.123412E+07
*TYPE 0Z,!
= 0.260000E+02
*TYPE 0ZZ,!
= 0.286000E+03
*
``````

So the algorithm is that for every letter, the current number is multiplied by 10, and then the number 1-26 that corresponds to the letter is added to the floating point value. Once the mantissa is exhausted, the value can still be increased by carry (but the exact letter is lost), and letters beyond 10 (`J`) "overflow" in any position.

And this is extremely cheap to implement, as this is the same algorithm that is used to convert ordinary digits.

All of this is quite different from how 6-bit character codes are used.

So maybe you should think of the "alphanumeric numbers" as some sort of string hash: It's a value assigned to a string that is unlikely to collide at least for short strings. And you can use it to compare strings (with low probability of false positives, if the expected strings are something like `YES` and `NO`), which seems to be the main use case.

• It is exactly the way inputting of 4 bit decimals (aka BCD) is done, reusing the existing function. For each decimal, shift the word by 4 and add that decimal. The except, since the input character is wider than 4 bit and not truncated to 4 bit in this process, its upper two bit will adds into the higher parts. Using strings like AAJJZ or AATTZ should nicely show any rippling effects. Commented Apr 6, 2023 at 3:27
• @Raffzahn PDP-8 doesn't have BCD arithmetic, and if you play around with `(1/2)-0.5` and `(1/5)-0.2` etc., it's easy to see that it Focal implements binary mantissa floating points, and not BCD ones. So it does not shift by 4 bits, it really multiplies by 10. And yes, anything in excess of 10 will cause rippling effects, not the higher bits. Commented Apr 6, 2023 at 3:58
• You should be able to enter `MY` for `NO` and `BEES` for `YES`. Commented Apr 6, 2023 at 21:51
• @A.I.Breveleri ah, that's unfortunate :) Commented Apr 7, 2023 at 3:19
• Ah, thanks for this! Implementing now... I assume if I hit a period I divide by 10^index, and I'll add support for + and -. Commented Apr 7, 2023 at 13:46