Page Last Altered:

**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.

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 |