8-Bit Software

The BBC and Master Computer Public Domain Library

Back to 8BS Or Back to Disassembly


Page Last Altered:

A746 LN

Submitted by Steve Fewell

Routine:LN
Name: LN (Natural Logarithm)
Starting Address: &A746
Entry criteria: The FWA contains the value to work with
Exit: The FWA contains the result.

Description:

Get the Numeric value (if integer then convert to Float, if String then Type Mismatch error).
If the number is zero or negative then generate a Log range error.

Set the FWB value to -1.0.
Scale the value in the FWA to a number between 1 and 2. [This is done by setting
the FWA exponent to #&81 if the Mantissa byte 1 value is less than #&B5, or to #&80 if
the FWA value is 0.0 or the Mantissa 1 value is more than #&B4].
The previous exponent is stored on the Stack (X). This will be used to calculate the
difference between the original and scaled exponents later on.
Note: If the FWA value is 0.0 or the Mantissa 1 value is more than #&B4 then the value
or the original exponent (on the stack) is incremented, to represent the exponent variance
(the actual difference) rather than the exact original value.

Subtract 1 from the FWA value to further reduce the the FWA value to a number between 0 and 1
(a fractional value). [This is done by adding FWB (value=-1) to the FWA].
Store this fractional value in Temporary Floating-Point variable address &047B.

Evaluate the LN continued-fraction expansion series (A861) with X=#&51, A=#&6F and Y=#&02.
Thus the parameters to the evaluate series routine are as follows:
Default value (if FWA value too small to calculate) = &BF6F = -0.5
First Floating-Point constant to use = &BF51.
Number of cycles to evaluate = #&02.

The series is evaluated as follows:
If FWA too small then return -0.5 (&BF6F).
FWA = 1/FWA (store in Temporary Floating-Point variable address &046C)
FWA = 0.546254168 + FWA    [Floating-Point constant &BF51]
FWA = -0.0513882861 / FWA    [Floating-Point constant &BF56]
FWA = 0.583293331 + FWA    [Floating-Point constant &BF5B]
FWA = &046C [1/orig FWA] + FWA
FWA = -0.0374986753 / FWA    [Floating-Point constant &BF60]
FWA = 0.750000063 + FWA    [Floating-Point constant &BF65]
FWA = &046C [1/orig FWA] + FWA
FWA = 0.33333334 / FWA    [Floating-Point constant &BF6A]
FWA = -0.5 + FWA    [Floating-Point constant &BF6F]

Multiply the series result by 5 * &047B (the scaled FWA value before series calculation was done)
This is achieved by multiplying the result by &047B twice and then adding &047B.
Store the FWA value in Temporary Floating-Point location &046C. This is the LN result
for the scaled value.

Subtract #&81 from the original exponent before the value was scaled. This will give
the difference between the exponent of the original value and the exponent of the scaled
value that was used for the series calculation.
Place this value into the FWA.
Multiply the FWA (exponent difference) by Floating-Point constant &BF4C (0.693147181).
Add &046C (the result calculated with the scaled value) to the FWA.
The value in the FWA is now the LN value of the original value.

Example 1:
Calculate LN(3.14)
3.14 => Exponent = &82, Mantissa 1 = &48, Mantissa 2 = &F5, Mantissa 3 = &C2, Mantissa 4 = &8F
Change Exponent to &81 to scale the value to 1.57 (exponent difference = 1)
Subtract 1 from the FWA to give 0.57, store this value in &047B.
Calculate reciple -> FWA = 1/FWA = 1.75438596. Store this value in location &046C.
FWA = 0.546254168 + FWA = 2.30064013291
FWA = -0.0513882861 / FWA = -0.0223365164
FWA = 0.583293331 + FWA = 0.56095681458
FWA = &046C + FWA = 2.3153427745823
FWA = -0.0374986753 / FWA = -0.0161957338
FWA = 0.750000063 + FWA = 0.73380432917
FWA = &046C + FWA = 2.488190289171
FWA = 0.33333334 / FWA = 0.133966176723
FWA = -0.5 + FWA = -0.366033823

FWA = FWA * 0.57 (&047B) = -0.20863927926778
FWA = FWA * 0.57 (again) = -0.11892438918
FWA = FWA + 0.57 = 0.451075610756108
This is the LN value of the scaled number (1.57). Store in &046C.
FWA = 1 (exponent difference) * 0.693147181 (&BF4C) = 0.693147181.
FWA = 0.451075610756108 + FWA = 1.14422279. This is the LN value of 3.14.


Example 2:
Calculate LN(15)
15 => Exponent = &84, Mantissa 1 = &70, Mantissa 2 = &00, Mantissa 3 = &00, Mantissa 4 = &00
Change Exponent to &81 to scale the value to 1.875 (exponent difference = 3)
Subtract 1 from the FWA to give 0.875, store this value in &047B.
Calculate reciple -> FWA = 1/FWA = 1.142857142857. Store this value in location &046C.
FWA = 0.546254168 + FWA = 1.689111310857
FWA = -0.0513882861 / FWA = -0.0304232680047
FWA = 0.583293331 + FWA = 0.552870062995
FWA = &046C + FWA = 1.69572720585
FWA = -0.0374986753 / FWA = -0.02211362486288
FWA = 0.750000063 + FWA = 0.727886438137
FWA = &046C + FWA = 1.8707435809941
FWA = 0.33333334 / FWA = 0.17818227114956
FWA = -0.5 + FWA = -0.3218177288504

FWA = FWA * 0.875 (&047B) = -0.28159051274413
FWA = FWA * 0.875 (again) = -0.246391698651115
FWA = FWA + 0.875 = 0.6286083013488848
This is the LN value of the scaled number (1.875). Store in &046C.
FWA = 3 (exponent difference) * 0.693147181 (&BF4C) = 2.079441543.
FWA = 0.6286083013488848 + FWA = 2.708049844. This is the LN value of 15.


Disassembly for the LN routine

A746   032 218 150 20 DA 96 JSR &96DA Get and check Float value
A749   032 242 163 20 F2 A3 JSR &A3F2 Float Sign
A74C   240 002 F0 02 BEQ 2 --> &A750
A74E   016 022 10 16 BPL 22 --> &A766
A750 ...Log range and -ve root Error messages...
A766 v 032 118 165 20 76 A5 JSR &A576 Clear FWB Mantissa bytes 2 to 5
A769   160 128 A0 80 LDY#&80
A76B ; 132 059 84 3B STY &3B
A76D = 132 061 84 3D STY &3D
A76F   200 C8 INY
A770 < 132 060 84 3C STY &3C
A772 0 166 048 A6 30 LDX &30
A774   240 006 F0 06 BEQ 6 --> &A77C
A776 1 165 049 A5 31 LDA &31
A778   201 181 C9 B5 CMP#&B5
A77A   144 002 90 02 BCC 2 --> &A77E
A77C   232 E8 INX
A77D   136 88 DEY
A77E   218 DA PHX
A77F 0 132 048 84 30 STY &30
A781   032 146 166 20 92 A6 JSR &A692 FWA = FWA + FWB
A784 { 169 123 A9 7B LDA#&7B
A786   032 019 165 20 13 A5 JSR &A513 Store FWA to &047B
A789 Q 162 081 A2 51 LDX#&51
A78B o 169 111 A9 6F LDA#&6F
A78D   160 002 A0 02 LDY#&02
A78F a 032 097 168 20 61 A8 JSR &A861 Evaluate continued-fraction expansion series
A792 { 169 123 A9 7B LDA#&7B
A794   032 161 169 20 A1 A9 JSR &A9A1 Multiply FWA by &047B
A797   032 166 166 20 A6 A6 JSR &A6A6 Multiply the FWA by argp [i.e. &047B again]
A79A   032 141 166 20 8D A6 JSR &A68D Add argp to the FWA [argp = &047B]
A79D   032 017 165 20 11 A5 JSR &A511 Store FWA to &046C
A7A0 h 104 68 PLA
A7A1 8 056 38 SEC
A7A2   233 129 E9 81 SBC#&81
A7A4   032 213 129 20 D5 81 JSR &81D5 Set FWA to 1-byte value (i.e. FWA = the exponent difference)
A7A7 L 169 076 A9 4C LDA#&4C
A7A9   032 212 169 20 D4 A9 JSR &A9D4 Multply FWA by &BF4C
A7AC   032 146 165 20 92 A5 JSR &A592 Set argp to &046C
A7AF   032 141 166 20 8D A6 JSR &A68D FWA = FWA + argp [&046C]
A7B2   169 255 A9 FF LDA#&FF
A7B4 ` 096 60 RTS

 


 Back to 8BS
Or