ZX Basic Features

 

The ‘Division Error’

If you run the following program on a standard Spectrum, or on an emulator with the standard ROM, then the results are predictably correct.

 

10 PRINT .25 = 1/4

20 PRINT .9999999948

30 FOR I = 0 TO 1 STEP .25 : PRINT I : NEXT I : PRINT “end”

 

If you run the same program on an emulator using a modified ROM, with the corrected “division error”, then the results are somewhat inaccurate.

 

Normal ZX ROM                                                      Modified ROM

1                                                                                  0

.99999999                                                                 1

0                                                                                  0

0.25                                                                            0.25

0.5                                                                               0.5

0.75                                                                            0.75

1.0                                                                               end

end

Clearly something is amiss.

 

Floating-point Arithmetic

 

The ZX81 and the ZX Spectrum use a similar floating-point number representation and the following applies to both machines.

A four byte, 32-bit mantissa is used with the most significant bit, the implied set bit, being used as a sign bit for the number.

This bit is reset to denote a positive number and left set to denote a negative number.

The byte that precedes the mantissa is the exponent byte. This holds the number of times the imaginary decimal point that precedes the mantissa has to be moved to restore the number from it’s normalized state.

The normal state is when the bits of the mantissa are moved left (or right) so that the most significant bit is set.

A number like a half ( .1 binary ) or three-quarters ( .11 binary) is already normalized and has a plus zero exponent ( $80).

A number like a quarter  ( .01 binary )  is shifted left and the exponent decreased ( $7F ).

A vast range of numbers, of which 1/65536 through 65536 is just a small subset, can be held accurately with a mantissa consisting of four zero bytes. 

In contrast, just as a third cannot be held accurately in the decimal system (giving .33333 recurring), so a tenth cannot be held accurately in a binary mantissa and becomes .00110011 recurring. Only machines like the Jupiter Ace, which use Binary Coded Decimal, can hold a tenth accurately.

 

Table 1.

ROMS

ZX ROM

Div 34th

DEC-TO-FP

BOTH

Internal Storage

.5

7F 7F FF FF FF

80 00 00 00 00

80 00 00 00 00

80 00 00 00 00

½

80 00 00 00 00

80 00 00 00 00

80 00 00 00 00

80 00 00 00 00

.25

7E 7F FF FF FF

7F 00 00 00 01

7E 7F FF FF FF

7F 00 00 00 00

¼

7F 00 00 00 00

7F 00 00 00 00

7F 00 00 00 00

7F 00 00 00 00

.125

7D 7F FF FF FF

7E 00 00 00 01

7D 7F FF FF FF

7E 00 00 00 00

1/8

7E 00 00 00 00

7E 00 00 00 00

7E 00 00 00 00

7E 00 00 00 00

.0625

7C 7F FF FF FF

7D 00 00 00 01

7C 7F FF FF FF

7D 00 00 00 00

1/16

7D 00 00 00 00

7D 00 00 00 00

7D 00 00 00 00

7D 00 00 00 00

.03125

7C 00 00 00 00

7C 00 00 00 01

7C 00 00 00 00

7C 00 00 00 01

1/32

7C 00 00 00 00

7C 00 00 00 00

7C 00 00 00 00

7C 00 00 00 00

.015625

7B 00 00 00 00

7B 00 00 00 01

7B 00 00 00 00

7B 00 00 00 00

1/64

7B 00 00 00 00

7B 00 00 00 00

7B 00 00 00 00

7B 00 00 00 00

.0078125

79 7F FF FF FF

7A 00 00 00 01

7A 00 00 00 00

7A 00 00 00 00

1/128

7A 00 00 00 00

7A 00 00 00 00

7A 00 00 00 00

7A 00 00 00 00

.00390625

79 00 00 00 00

79 00 00 00 01

79 00 00 00 00

79 00 00 00 00

1/256

79 00 00 00 00

79 00 00 00 00

79 00 00 00 00

79 00 00 00 00

.001953125

77 7F FF FF FF

78 00 00 00 01

77 7F FF FF FF

78 00 00 00 00

1/512

78 00 00 00 00

78 00 00 00 00

78 00 00 00 00

78 00 00 00 00

.000976525

76 7F FF FF FF

77 00 00 00 01

76 7F FF FF FF

77 00 00 00 00

1/1024

77 00 00 00 00

77 00 00 00 00

77 00 00 00 00

77 00 00 00 00

Boolean Logic

.5 = 1/2

TRUE

TRUE

TRUE

TRUE

½  = .5

FALSE

TRUE

TRUE

TRUE

.25 = 1/4

TRUE

FALSE

TRUE

TRUE

¼ = .25

FALSE

FALSE

FALSE

TRUE

.125 = 1/8

TRUE

FALSE

TRUE

TRUE

1/8 =.125

FALSE

FALSE

FALSE

TRUE

.0625 = 1/16

TRUE

FALSE

TRUE

TRUE

1/16 = .0625

FALSE

FALSE

FALSE

TRUE

.03125 = 1/32

TRUE

FALSE

TRUE

FALSE

1/32 = .03125

TRUE

FALSE

TRUE

FALSE

.015625 = 1/64

TRUE

FALSE

TRUE

TRUE

1/64 = .015625

TRUE

FALSE

TRUE

TRUE

.0078125 = 1/128

TRUE

FALSE

TRUE

TRUE

1/128 = .0078125

FALSE

FALSE

TRUE

TRUE

.00390625=1/256

TRUE

FALSE

TRUE

TRUE

1/256=.00390625

TRUE

FALSE

TRUE

TRUE

Fractional Loop Steps

.5

CORRECT

CORRECT

CORRECT

CORRECT

.25

CORRECT

WRONG

CORRECT

CORRECT

.125

CORRECT

WRONG

CORRECT

CORRECT

.0625

CORRECT

WRONG

CORRECT

CORRECT

.03125

CORRECT

WRONG

CORRECT

WRONG

.015625

CORRECT

WRONG

CORRECT

CORRECT

.0078125

CORRECT

WRONG

CORRECT

CORRECT

Print values

.123456785

0.12345678

0.12345679

0.12345678

0.12345678

.100000015

0.10000001

0.10000002

0.10000001

0.10000002

.200000015

0.20000002

0.20000002

0.20000002

0.20000002

.876543215