5) The flow chart and last mysteries.
Let us have a look at the calculation flow chart .
We can now explain the latest mysteries.
The box labeled “ln24” is entered when a change of “constant” is needed. Since a[s] where used at address 02027 to test if calculation part 1 was finished, the original value of a[s] must be restored and incremented to start a new constant step (it is the number of SR for the new constant).
At 02003, we make room in C for the current pseudo quotient qi (the previous one being shifted right to be kept). The set of qi values set is the result of part 1 calculation.
In 2004, A is normalized, saving accuracy by suppressing loading zeros (see fine tuning).
Now we are entering the box “ln26”. At 02022, the pseudo multiplication process is prepared, A being copied in B: A is going to be shifted but B retains a non shifted value.
Subroutine “eca” is called to calculate exponent qi (addresses 02225 to 02232). The number of SR to do is in a[s] and the programs loops and shifts right a[wp] the number of times needed.
When exiting the loop, a[s] is set to zero and the pseudo multiplication is done (address 02231), then two tests take place.
First in 02025, after a[p] has been decremented, a test for a “carry” is done.
This is a main part of the algorithm in 10’s complemented form: each of pseudo multiplication process can not generate a “borrow” ; this implements equation (see above).
Note that in the implementation, a[p] is the byte 12 of the machine register A. It is reserved for the overflow of pseudo multiplication done in 02231 (A + B -> A). This “carry” is the signal we can’t do any more pseudo multiplication process for this constant:
- If “no”, the pseudo multiplication process must be
done once more with the same constant. Box ln25 is entered and current value of
qj is incremented (c[s]), then ln26 follows once more.
- If “yes”, the constant must be changed but we must check first whether we are
not at the end of part1 computation (6 constants processed).
To do this second test, we save A in B (address 02026) and we double a[s] value and check for a carry (a[s] < 5, we use only 6 constants).
If there is no carry in this second test, we change the constant (by simply incrementing a[s] at address 02002).If “yes”, part1 calculation is done, the result is the set of qi in C and we go to part 2.
In our example the end of part1 can be seen at break point [CP7], where the C register holds the result “762311”:
02030: .......111 -> 02001 if no carry go to ln24
A=00322882267342 B=59322885496164 C=76231144000000
D=00000000000000 M=00000000000000 P=c S=0.2...6789.b
In order to completely master the first part of the algorithm, please take time to study in the trace the two following break points:
- [CP5] Here we process constant 1.01 which
is used 3 times (q2=3, SR=2); the break point is placed at the start of 1.01
calculation,
- [CP6] is the place where a test is made to decide to do another
loop with 1.01 (SR=2),
- [CP7] is the place at the end of process for 1.01 where it is
decided to change to 1.001 constant.
I hope this is clear enough for part 1, please give me feedback.
6) The logarithm generation.
Now we are ready to start the part 2 of the algorithm that will lead to the final result ln(4.4). We are at [CP8] in the trace listing and the partial result is:
C=76231144000000 : the qj
and
A=00322882267342 : the so called remainder.
All we have now to do is to add together A and the 6 pseudo multiplicands; each of them is made of a constant ln(1 + 10-j) found in ROM applied a number of times stored in the C register (qj):
- 7 times ln(1.00001),
- 6 times ln(1.0001),
- 2 times ln(1.001),
- 3 times ln(1.01),
- 1 time ln(1.1),
and 1 time ln(2) and finally subtract the sum from ln(10).
This part is very straightforward and easy to comment.
At address 02032 we are calling routine pqo23 to build ln(1.00001) which is correctly aligned C=00999995000000.
Note that simple “patterns” like “999995000000” was not stored actually in ROM, but forged –on the fly- very simply.
Then subroutine pmu22 is called 7 times to add ln(1.00001) to the remainder: the number or times is decremented directly in C and will be shifted left and lost at the end of the loop [CP9] address 02243.
Partial result is then: A=07322847267342 and C=06231144000000.
Next step, we are going to add 6 times ln(1.0001) and we build this pattern C=00999950000000 in the code following [CP10].
Note the operation of normalization of the partial result in [CP11] address 02234, to align correctly the 2 numbers in the pseudo multiplication at pmu23 (02237).
First time is
02237 pmu23: a + b -> a[w]
A=01732234726734 B=00999950000000 C=52311440000000
And 6th is
02237 pmu23: a + b -> a[w]
A=06731984726734 B=00999950000000 C=02311440000000
Afterwards, this kind of process goes on for others qj exponents {2311} and leads at [CP12] where ln(2) is loaded C=00693147180553 (address 02272 to 02352) and where finally [CP13] the sum is completely calculated:
02237 pmu23: a + b -> a[w]
A=00820980552045 B=00693147180553 C=04400000000000
Finally, at address 02366, ln(10) is loaded [CP14] C=02302585093000 and the previous sum will be subtracted from this value to take care of the mantissa range, giving the final result of this calculation ln(4.4)= 1.481604540955:
02052: a exchange c[w]
A=02302585093000 B=44000000000000 C=00820980552045
02053: a - c -> c[w]
A=02302585093000 B=44000000000000 C=01481604540955
I hope this
long explanation is clear enough.
It is an algorithm, so you cannot read it like you read your newspaper.
But it’s worth digging since it is pure computer
history and a Master Class!
________________________
To David Cochran.
Monday, 21 November 2005.