Difference between revisions of "Floating Point number format"
m (1 revision) |
(Correcting the second Acorn BASIC example - negative number should have sign bit set in the 'stored as' value) |
||
(4 intermediate revisions by 2 users not shown) | |||
Line 5: | Line 5: | ||
All numbers, other than zero, can be expressed as m*10^e. You may be familiar with this form known as exponential format. For example: | All numbers, other than zero, can be expressed as m*10^e. You may be familiar with this form known as exponential format. For example: | ||
− | + | 100 is 1*10^2 | |
5000 is 5*10^3 | 5000 is 5*10^3 | ||
− | + | 0.5 is 5*10^-1 | |
Exactly the same can be done using base 2, expressing numbers as m*2^e, for example: | Exactly the same can be done using base 2, expressing numbers as m*2^e, for example: | ||
− | + | 4 is 1*2^2 | |
− | + | -8 is -1*2^3 | |
− | + | 12 is 1.5*2^3 | |
− | -0.5 is -1*2^-1 | + | -0.5 is -1*2^-1 |
− | In | + | In floating point format, the manitissa is ''normalised'' by being multiplied or divided by 2, and the exponent reduced or increased, until the mantissa m is in the range 0.5 to 1, excluding 1, for example: |
− | + | 4 is 0.5*2^3 | |
− | + | -8 is -0.5*2^4 | |
− | + | 12 is 0.75*2^4 | |
-0.5 is -0.5*2^0 | -0.5 is -0.5*2^0 | ||
− | + | Normalising the mantissa means that the first bit of the mantissa is always 1. That means that as we know it will always be 1, it can be used to hold something else, and it is used to hold the sign bit. | |
To allow negative exponents an ''excess'' is added to it. Acorn BASICs use excess &80, where &80 represents an exponent of 0; Russell BASICs uses excess &7F, where &7F represents an exponent of 0. | To allow negative exponents an ''excess'' is added to it. Acorn BASICs use excess &80, where &80 represents an exponent of 0; Russell BASICs uses excess &7F, where &7F represents an exponent of 0. | ||
+ | This can be represented as: | ||
+ | |||
+ | 7 0 31 0 | ||
+ | +-+-------+ +-+-------+--------+--------+--------+ | ||
+ | |S|eeeeeee| |S|mmmmmmm|mmmmmmmm|mmmmmmmm|mmmmmmmm| | ||
+ | +-+-------+ +-+-------+--------+--------+--------+ | ||
+ | sign exponent sign implied-1 mantissa | ||
So, for example on Acorn BASICs: | So, for example on Acorn BASICs: | ||
− | + | 4 is exponent &83, sign 0, mantissa &80000000, stored as &83,&00000000 | |
− | + | -8 is exponent &84, sign 1, mantissa &80000000, stored as &84,&80000000 | |
− | + | 12 is exponent &84, sign 0, mantissa &C0000000, stored as &84,&40000000 | |
− | -0.5 is exponent &80, mantissa & | + | -0.5 is exponent &80, sign 1, mantissa &80000000, stored as &80,&80000000 |
Zero is a special case and is stored as five zero bytes. Some versions of BBC BASIC extend this and use a zero exponent to indicate that the real actually holds an integer value. For example: | Zero is a special case and is stored as five zero bytes. Some versions of BBC BASIC extend this and use a zero exponent to indicate that the real actually holds an integer value. For example: | ||
Line 38: | Line 45: | ||
&00, &00000000 is 0 | &00, &00000000 is 0 | ||
&00, &00000080 is 128 (where implemented) | &00, &00000080 is 128 (where implemented) | ||
− | &00, &FFFFFFFE is -2 (where implemented) | + | &00, &FFFFFFFE is -2 (where implemented) |
To convert a real to an integer the mantissa must be multiplied by two and the exponent consequently decreased until the exponent is zero (ie &80 on Acorn BASICs, &7F on Russell BASICs), a process known as ''denormalisation''. For example, converting 0.5*2^3 back to 4*2^0. | To convert a real to an integer the mantissa must be multiplied by two and the exponent consequently decreased until the exponent is zero (ie &80 on Acorn BASICs, &7F on Russell BASICs), a process known as ''denormalisation''. For example, converting 0.5*2^3 back to 4*2^0. | ||
Line 45: | Line 52: | ||
== Implementations == | == Implementations == | ||
− | === | + | === 6502 BASIC === |
− | + | [[6502 BBC BASIC|6502 BASIC]] stores reals in memory high-to-low as: | |
+ | address+0 address+4 | ||
mantissa.hi, mantissa.middle, mantissa.middle, mantissa.lo, exponent | mantissa.hi, mantissa.middle, mantissa.middle, mantissa.lo, exponent | ||
− | The only 32-bit integer | + | The only 32-bit integer that 6502 BASIC allows to be stored in a real is zero. 6502 BASIC uses excess-&80 for the exponent, so &80 represents an exponent of zero. |
− | === | + | === Non-6502 BASICs === |
− | + | All other versions of BBC BASIC store reals in memory low-to-high as: | |
+ | address+0 address+4 | ||
mantissa.lo, mantissa.middle, mantissa.middle, mantissa.hi, exponent | mantissa.lo, mantissa.middle, mantissa.middle, mantissa.hi, exponent | ||
− | + | Acorn BASICs use excess-&80 for the exponent, so &80 represents an exponent of zero. Zero is the only 32-bit integer than can be stored in a real by setting the exponent to zero. | |
+ | |||
+ | Russell BASICs use excess-&7F for the exponent, so &7F represents an exponent of zero. Any 32-bit integer can be stored in a real by setting the exponent to zero. | ||
− | |||
J.G.Harston's PDP-11 BASIC stores reals in memory low-to-high, and allows 32-bit integers to be stored by setting the exponent to zero, as in Russell BASICs. | J.G.Harston's PDP-11 BASIC stores reals in memory low-to-high, and allows 32-bit integers to be stored by setting the exponent to zero, as in Russell BASICs. | ||
+ | |||
+ | Where an exponent of zero can be used to store an integer, that means that if ''num'' is an integer and stored in memory with '''|address=num''' then |address=!address. If ''num'' is less than 256, then |address=!address=?address. Similarly, if ''num'' is stored in memory with '''!address=num:address?4=0''' then, again, |address=!address. | ||
+ | |||
+ | === 64-bit BASIC === | ||
+ | ARM BASIC VI and Windows BASIC can use 8-byte floating point numbers. | ||
== See Also == | == See Also == | ||
− | * [[ | + | * [[Denormalising a number]] |
− | * [[ | + | * [[Normalising a number]] |
[[User:Jgharston|Jgharston]] 23:26, 30 April 2008 (BST) | [[User:Jgharston|Jgharston]] 23:26, 30 April 2008 (BST) | ||
+ | [[User:Jgharston|Jgharston]] ([[User talk:Jgharston|talk]]) 02:30, 10 July 2021 (CEST) |
Latest revision as of 16:23, 27 September 2024
Contents
Description
BBC BASIC stores real (non-integer) numbers in five bytes in a format known as "five-byte floating point". This splits the number into two components - a one-byte exponent and a four-byte mantissa.
All numbers, other than zero, can be expressed as m*10^e. You may be familiar with this form known as exponential format. For example:
100 is 1*10^2 5000 is 5*10^3 0.5 is 5*10^-1
Exactly the same can be done using base 2, expressing numbers as m*2^e, for example:
4 is 1*2^2 -8 is -1*2^3 12 is 1.5*2^3 -0.5 is -1*2^-1
In floating point format, the manitissa is normalised by being multiplied or divided by 2, and the exponent reduced or increased, until the mantissa m is in the range 0.5 to 1, excluding 1, for example:
4 is 0.5*2^3 -8 is -0.5*2^4 12 is 0.75*2^4 -0.5 is -0.5*2^0
Normalising the mantissa means that the first bit of the mantissa is always 1. That means that as we know it will always be 1, it can be used to hold something else, and it is used to hold the sign bit.
To allow negative exponents an excess is added to it. Acorn BASICs use excess &80, where &80 represents an exponent of 0; Russell BASICs uses excess &7F, where &7F represents an exponent of 0. This can be represented as:
7 0 31 0 +-+-------+ +-+-------+--------+--------+--------+ |S|eeeeeee| |S|mmmmmmm|mmmmmmmm|mmmmmmmm|mmmmmmmm| +-+-------+ +-+-------+--------+--------+--------+ sign exponent sign implied-1 mantissa
So, for example on Acorn BASICs:
4 is exponent &83, sign 0, mantissa &80000000, stored as &83,&00000000 -8 is exponent &84, sign 1, mantissa &80000000, stored as &84,&80000000 12 is exponent &84, sign 0, mantissa &C0000000, stored as &84,&40000000 -0.5 is exponent &80, sign 1, mantissa &80000000, stored as &80,&80000000
Zero is a special case and is stored as five zero bytes. Some versions of BBC BASIC extend this and use a zero exponent to indicate that the real actually holds an integer value. For example:
&00, &00000000 is 0 &00, &00000080 is 128 (where implemented) &00, &FFFFFFFE is -2 (where implemented)
To convert a real to an integer the mantissa must be multiplied by two and the exponent consequently decreased until the exponent is zero (ie &80 on Acorn BASICs, &7F on Russell BASICs), a process known as denormalisation. For example, converting 0.5*2^3 back to 4*2^0.
Of course, if the real holds a noninteger, then when the mantissa is multiplied some bits will overflow before the exponent has reached zero. Depending on what you want to do with the denormalised number, a program would either ignore those overflowed bits, giving a truncated integer, or the overflow flags an error to indicate that the real could not be denormalised to an integer.
Implementations
6502 BASIC
6502 BASIC stores reals in memory high-to-low as:
address+0 address+4 mantissa.hi, mantissa.middle, mantissa.middle, mantissa.lo, exponent
The only 32-bit integer that 6502 BASIC allows to be stored in a real is zero. 6502 BASIC uses excess-&80 for the exponent, so &80 represents an exponent of zero.
Non-6502 BASICs
All other versions of BBC BASIC store reals in memory low-to-high as:
address+0 address+4 mantissa.lo, mantissa.middle, mantissa.middle, mantissa.hi, exponent
Acorn BASICs use excess-&80 for the exponent, so &80 represents an exponent of zero. Zero is the only 32-bit integer than can be stored in a real by setting the exponent to zero.
Russell BASICs use excess-&7F for the exponent, so &7F represents an exponent of zero. Any 32-bit integer can be stored in a real by setting the exponent to zero.
J.G.Harston's PDP-11 BASIC stores reals in memory low-to-high, and allows 32-bit integers to be stored by setting the exponent to zero, as in Russell BASICs.
Where an exponent of zero can be used to store an integer, that means that if num is an integer and stored in memory with |address=num then |address=!address. If num is less than 256, then |address=!address=?address. Similarly, if num is stored in memory with !address=num:address?4=0 then, again, |address=!address.
64-bit BASIC
ARM BASIC VI and Windows BASIC can use 8-byte floating point numbers.
See Also
Jgharston 23:26, 30 April 2008 (BST) Jgharston (talk) 02:30, 10 July 2021 (CEST)