5

The ZX Spectrum has two formats for storing numbers, both 40 bits, or five bytes.

  • The first is a floating point format, which consists of one exponent byte, and four mantissa bytes. The first bit of the mantissa is assumed to be 1 and so is not stored; this frees up one bit in the mantissa to store the sign (+/-).

  • The second is some kind of 16-bit integer format, fluffed up to fit the same amount of space as a float. This format consists of one zero byte, one 0xFF byte, two bytes containing the 16-bit integer, stored little-endian, and a dummy byte which I believe is ignored.

What is the motive for including this second format? Initially, I thought that the few things which are certainly integers, like a BASIC line number or valid arguments to POKE or AT and so on, those can be assumed to be integers so that arithmetic can be done more quickly. But then, the computer will have to check that the first two bytes equal 0xFF00 before proceeding to use the number. And that would incur a cost on any floating point calculation.

What if a mantissa happens to start with at least seven eight ones, and the sign happens to be negative, and the exponent happens to be zero? I see (the potential for) a bug there. That scenario would mean that the first two bytes of the float would be 0x00 and 0xff, so that could confuse the calculator routines.

  • 3
    I think the ZX81 is exactly the same in this regard, but not the ZX80. The ZX80 has an integer-only BASIC. – Wilson Jan 20 at 8:27
10

The ZX Spectrum has two formats for storing numbers, both 40 bits, or five bytes.

Jup, like many other machines - one for float and one for integer.

The second is some kind of 16-bit integer format,

Not some kind, but the integer format.

fluffed up to fit the same amount of space as a float.

Which was done to make variable memory management easy.

and a dummy byte which I believe is ignored.

But set to zero when an integer is stored

What is the motive for including this second format?

It's got several advantages

  • A one size fits all (numeric variables) approach, so memory management doesn't need to distinguish between integer and float

  • Integers are automatic detected, thus no need to declare integer variables like in other BASICs

  • Integers are always stored as integers

  • Calculation with integers can be sped up by avoiding conversion

  • Calculations with integers aren't harmed by being stored in float

[...] like a BASIC line number

I assume you mean for GO TO or alike, as line numbers themselves are handled (and stored) differently.

or valid arguments to POKE or AT and so on, those can be assumed to be integers so that arithmetic can be done more quickly.

Exactly.

But then, the computer will have to check that the first two bytes equal 0xFF00 before proceeding to use the number.

They are a marker. Which speeds up execution a lot. If numbers in like a POKE would be stored as float, then for each execution a float to integer conversion must be called (in fact twice; once for the byte to be poked as well). So instead conversion is only to be done if either marker byte is not present. A serious saving.

And that would incur a cost on any floating point calculation.

That's what? Two pairs of compare and jump, the second pair only executed at all for a tiny fraction of numbers? It's worth keeping in mind that a differentiation between FP or integer input from a variable has to be done anyway - so checking some flag stored at another position (where?) must happen - which makes the solution chosen almost free of cost in case of FP. Setup by a huge saving in not having to convert from FP if the number is to be used as integer anyway.

What if a mantissa happens to start with at least seven eight ones, and the sign happens to be negative, and the exponent happens to be zero? I see (the potential for) a bug there. That scenario would mean that the first two bytes of the float would be 0x00 and 0xff, so that could confuse the calculator routines.

No bug. It's a marker checked beforehand. Such a configuration is simply not an FP number. So Sinclair BASIC misses out of a tiny fraction of possible numbers compared to other BASICs with a similar encoding for FP. Not a big deal.

Especially not when it simplifies coding and speeds up execution as trade off.

P.S.: The whole details are covered in chapter 24 of the manual.


As there was a discussion about the impact of the introduction of this marker format on the range of FP numbers possible, be assured it's a rather small one.

The way it is implemented, it supports numbers from E-127 (Exponent encoded as 01h) to E+127 (FFh) (*1) without any restrictions. Without the integer marker it would go down to E-128. Sacrificing this for a clean integer handling in the same space and doing away with special integer variables is a cheap price to be payed.

Another idea that came up in discussion was the use of an appropriate exponent to simply use states where FP representation would match integer anyway. Like E+15, where the next two bytes would be exactly like the corresponding signed integer. Sounds cool at first, but it would end up in creating a mess.

For one, it only works with signed integer. Not a hurdle at first, as BASIC treats them that way anyway (*2), but latest when it comes to numbers smaller than +/-16384 representation would end up being not normalized - something that will screw floating point handling - unless additional checks are added, which in turn would slow down all FP calculation.

Next, and equally important, FP numbers in the range of integers that do have significant digits beyond the 15th (and thus being most definitive FP) would also identify as integer. To avoid this the trailing bytes (#4 and #5) must need to be checked for zero as well for safe identification as integer, making it 3 bytes to be tested instead of two, again slowing down identification.

Bottom line, the selected method is quite nice and solves its purpose at least as well as the more common MS-BASIC way of using variable identifiers (*3).


*1 - Exponents are encoded with high bit set for positive values to allow unsigned operations be used instead of signed. Or as the manuals put it " exponent +128 in the first byte".

*2 - Not sure ATM, but I think BASIC stores inline values as well in unsigned manner.

*3 - Depending on the way BASIC lines are stored, the the MS method of adding a type identifier (like %) may result in an additional byte per occurrence within the program, making integer variables even more costly.

  • Can you clarify why such a configuration simply is not an FP number? What happens to the numbers which would have been expressed by a mantissa starting with eight ones, a zero exponent and a negative sign bit? – Wilson Jan 20 at 14:33
  • @Wilson Why is simple: Because. What's a valid number is defined by whoever implements the routines. Isn't it? Here E-128 is outside the range of this float implementation. The same ways as a number with an exponent of E-129 (or more) would be outside without that definition. It simply means that Sinclair BASIC 'only' handles numbers between E-127 to E+127 - no E+128 anymore. Not only no real loss, and now even symetric. – Raffzahn Jan 20 at 14:52
  • Can you say why "it simplifies coding", as compared with a solution that simply checks if the exponent is 32? Because if E=32, then the mantissa is a signed 32 bit integer. Easy. – Wilson Jan 20 at 15:14
  • 1
    Ah, now I understand. Because in other words, if the first byte is zero, it's not an exponent. – Wilson Jan 20 at 15:36
  • 1
    So-called NaN Boxing is a technique still used in some programming languages today. – JdeBP Jan 25 at 18:08
3

Doing integer arithmetic is by some orders of magnitude faster as floating point. So if there is a statement like

LET a = b + c

the interpreter would first check if both a and b are integers. If yes, then it can proceed with a simple 16-bit addition, like ADD HL, BC to get the result, and directly store it into c. Otherwise, it would have to do an expensive floating point addition.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.