| Routines

3713: THE 'NATURAL LOGARITHM' FUNCTION (offset +25)

The address of this routine is found in the table of addresses. It is called via the calculator literal +25 by the routine at to_power. It is also called indirectly via fp_calc_2. This subroutine handles the function LN X and is the second of the four routines that use the series generator to produce Chebyshev polynomials. The approximation to LN X is found as follows: i. X is tested and report A is given if X is not positive. ii. X is then split into its true exponent, e', and its mantissa X'=X/(2**e'), where 0.5<=X'<1. iii. The required value Y1 or Y2 is formed: if X'>0.8 then Y1=e'*LN 2, otherwise Y2=(e'-1)*LN 2. iv. If X'>0.8 then the quantity X'-1 is stacked; otherwise 2*X'-1 is stacked. v. Now the argument Z is formed, being 2.5*X'-3 if X'>0.8, otherwise 5*X'-3. In each case, -1<=Z<=1, as required for the series to converge. vi. The series generator is used to produce the required function. vii. Finally a simple multiplication and addition leads to LN X being returned as the 'last value'.
ln | 3713 | RST $28 | X
Perform step i.
| 3714 | DEFB $3D | re_stack: X (in full floating-point form)
| 3715 | DEFB $31 | duplicate: X, X
| 3716 | DEFB $37 | greater_0: X, (1/0)
| 3717 | DEFB $00 | jump_true to VALID: X
| 3718 | DEFB $04 | multiply: X
| 3719 | DEFB $38 | end_calc: X
Report A - Invalid argument.
| 371A | RST $08 | Call the error handling routine.
| 371B | DEFB $09
Perform step ii.
VALID | 371C | DEFB $A0 | stk_zero: X, 0 (the deleted 1 is overwritten with zero)
| 371D | DEFB $02 | delete: X
| 371E | DEFB $38 | end_calc: X
| 371F | LD A,(HL) | The exponent, e, goes into A.
| 3720 | LD (HL),$80 | X is reduced to X'.
| 3722 | CALL STACK_A | The stack holds: X', e.
| 3725 | RST $28 | X', e
| 3726 | DEFB $34 | stk_data: X', e, 128
| 3727 | DEFB $38,$00
| 3729 | DEFB $03 | subtract: X', e'
Perform step iii.
| 372A | DEFB $01 | exchange: e', X'
| 372B | DEFB $31 | duplicate: e', X', X'
| 372C | DEFB $34 | stk_data: e', X', X', 0.8
| 372D | DEFB $F0,$4C,$CC,$CC,$CD
| 3732 | DEFB $03 | subtract: e', X', X'-0.8
| 3733 | DEFB $37 | greater_0: e', X', (1/0)
| 3734 | DEFB $00 | jump_true to GRE_8: e', X'
| 3735 | DEFB $08
| 3736 | DEFB $01 | exchange: X', e'
| 3737 | DEFB $A1 | stk_one: X', e', 1
| 3738 | DEFB $03 | subtract: X', e'-1
| 3739 | DEFB $01 | exchange: e'-1, X'
| 373A | DEFB $38 | end_calc
| 373B | INC (HL) | Double X' to give 2*X'.
| 373C | RST $28 | e'-1, 2*X'
GRE_8 | 373D | DEFB $01 | exchange: X', e' (X'>0.8) or 2*X', e'-1 (X'<=0.8)
| 373E | DEFB $34 | stk_data: X', e', LN 2 or 2*X', e'-1, LN 2
| 373F | DEFB $F0,$31,$72,$17,$F8
| 3744 | DEFB $04 | multiply: X', e'*LN 2=Y1 or 2*X', (e'-1)*LN 2=Y2
Perform step iv.
| 3745 | DEFB $01 | exchange: Y1, X' (X'>0.8) or Y2, 2*X' (X'<=0.8)
| 3746 | DEFB $A2 | stk_half: Y1, X', .5 or Y2, 2*X', .5
| 3747 | DEFB $03 | subtract: Y1, X'-.5 or Y2, 2*X'-.5
| 3748 | DEFB $A2 | stk_half: Y1, X'-.5, .5 or Y2, 2*X'-.5, .5
| 3749 | DEFB $03 | subtract: Y1, X'-1 or Y2, 2*X'-1
Perform step v.
| 374A | DEFB $31 | duplicate: Y, X'-1, X'-1 or Y2, 2*X'-1, 2*X'-1
| 374B | DEFB $34 | stk_data: Y1, X'-1, X'-1, 2.5 or Y2, 2*X'-1, 2*X'-1, 2.5
| 374C | DEFB $32,$20
| 374E | DEFB $04 | multiply: Y1, X'-1, 2.5*X'-2.5 or Y2, 2*X'-1, 5*X'-2.5
| 374F | DEFB $A2 | stk_half: Y1, X'-1, 2.5*X'-2.5, .5 or Y2, 2*X'-1, 5*X'-2.5, .5
| 3750 | DEFB $03 | subtract: Y1, X'-1, 2.5*X'-3=Z or Y2, 2*X'-1, 5*X'-3=Z
Perform step vi, passing to the series generator the parameter '12', and the twelve constants required.
| 3751 | DEFB $8C | series_0C: Y1, X'-1, Z or Y2, 2*X'-1, Z
| 3752 | DEFB $11,$AC |
| 3754 | DEFB $14,$09 |
| 3756 | DEFB $56,$DA,$A5 |
| 3759 | DEFB $59,$30,$C5 |
| 375C | DEFB $5C,$90,$AA |
| 375F | DEFB $9E,$70,$6F,$61 |
| 3763 | DEFB $A1,$CB,$DA,$96 |
| 3767 | DEFB $A4,$31,$9F,$B4 |
| 376B | DEFB $E7,$A0,$FE,$5C,$FC |
| 3770 | DEFB $EA,$1B,$43,$CA,$36 |
| 3775 | DEFB $ED,$A7,$9C,$7E,$5E |
| 377A | DEFB $F0,$6E,$23,$80,$93 |
At the end of the last loop the 'last value' is: LN X'/(X'-1) if X'>0.8 LN (2*X')/(2*X'-1) if X'<=0.8 Perform step vii.
| 377F | DEFB $04 | multiply: Y1=LN (2**e'), LN X' or Y2=LN (2**(e'-1)), LN (2*X')
| 3780 | DEFB $0F | addition: LN (2**e')*X')=LN X or LN (2**(e'-1)*2*X')=LN X
| 3781 | DEFB $38 | end_calc: LN X
| 3782 | RET | Finished: 'last value' is LN X.