Prev: 11733 Up: Map Next: 12171
11747: THE 'PRINT A FLOATING-POINT NUMBER' SUBROUTINE
 Used by the routines at PR_ITEM_1 and str. This subroutine prints x, the 'last value' on the calculator stack. The print format never occupies more than 14 spaces. The 8 most significant digits of x, correctly rounded, are stored in an ad hoc print buffer in mem-3 and mem-4. Small numbers, numerically less than 1, and large numbers, numerically greater than 2↑27, are dealt with separately. The former are multiplied by 10↑n, where n is the approximate number of leading zeros after the decimal, while the latter are divided by 10↑(n-7), where n is the approximate number of digits before the decimal. This brings all numbers into the middle range, and the number of digits required before the decimal is built up in the second byte of mem-5. Finally the printing is done, using E-format if there are more than 8 digits before the decimal or, for small numbers, more than 4 leading zeros after the decimal. The following program shows the range of print formats: 10 FOR a=-11 TO 12: PRINT SGN a*9↑a,: NEXT a i. First the sign of x is taken care of: If x is negative, the subroutine jumps to PF_NEGTVE, takes ABS x and prints the minus sign. If x is zero, x is deleted from the calculator stack, a '0' is printed and a return is made from the subroutine. If x is positive, the subroutine just continues. PRINT_FP 11747 RST 40 Use the calculator. 11748 DEFB 49 duplicate: x, x 11749 DEFB 54 less_0: x, (1/0) Logical value of x. 11750 DEFB 0,11 jump_true to PF_NEGTVE: x 11752 DEFB 49 duplicate: x, x 11753 DEFB 55 greater_0: x, (1/0) Logical value of x. 11754 DEFB 0,13 jump_true to PF_POSTVE: x Hereafter x'=ABS x. 11756 DEFB 2 delete: - 11757 DEFB 56 end_calc: - 11758 LD A,"0" Enter the character code for '0'. 11760 RST 16 Print the '0'. 11761 RET Finished as the 'last value' is zero. PF_NEGTVE 11762 DEFB 42 abs: x' x'=ABS x. 11763 DEFB 56 end_calc: x' 11764 LD A,"-" Enter the character code for '-'. 11766 RST 16 Print the '-'. 11767 RST 40 Use the calculator again. PF_POSTVE 11768 DEFB 160 stk_zero: The 15 bytes of mem-3, mem-4 and mem-5 are now initialised to zero to be used for a print buffer and two counters. 11769 DEFB 195,196,197 11772 DEFB 2 delete: The stack is cleared, except for x'. 11773 DEFB 56 end_calc: x' 11774 EXX HL', which is used to hold calculator offsets (e.g. for 'STR\$'), is saved on the machine stack. 11775 PUSH HL 11776 EXX ii. This is the start of a loop which deals with large numbers. Every number x is first split into its integer part i and the fractional part f. If i is a small integer, i.e. if -65535<=i<=65535, it is stored in DE' for insertion into the print buffer. PF_LOOP 11777 RST 40 Use the calculator again. 11778 DEFB 49 duplicate: x', x' 11779 DEFB 39 int: x', INT (x')=i 11780 DEFB 194 st_mem_2: (i is stored in mem-2). 11781 DEFB 3 subtract: x'-i=f 11782 DEFB 226 get_mem_2: f, i 11783 DEFB 1 exchange: i, f 11784 DEFB 194 st_mem_2: (f is stored in mem-2). 11785 DEFB 2 delete: i 11786 DEFB 56 end_calc: i 11787 LD A,(HL) Is i a small integer (first byte zero) i.e. is ABS i<=65535? 11788 AND A 11789 JR NZ,PF_LARGE Jump if it is not. 11791 CALL INT_FETCH i is copied to DE (i, like x', >=0). 11794 LD B,16 B is set to count 16 bits. 11796 LD A,D D is copied to A for testing: is it zero? 11797 AND A 11798 JR NZ,PF_SAVE Jump if it is not zero. 11800 OR E Now test E. 11801 JR Z,PF_SMALL Jump if DE is zero: x is a pure fraction. 11803 LD D,E Move E to D and set B for 8 bits: D was zero and E was not. 11804 LD B,8 PF_SAVE 11806 PUSH DE Transfer DE to DE', via the machine stack, to be moved into the print buffer at PF_BITS. 11807 EXX 11808 POP DE 11809 EXX 11810 JR PF_BITS Jump forward. iii. Pure fractions are multiplied by 10↑n, where n is the approximate number of leading zeros after the decimal; and -n is added to the second byte of mem-5, which holds the number of digits needed before the decimal; a negative number here indicates leading zeros after the decimal. PF_SMALL 11812 RST 40 i (i=zero here) 11813 DEFB 226 get_mem_2: i, f 11814 DEFB 56 end_calc: i, f Note that the stack is now unbalanced. An extra byte 'DEFB 2, delete' is needed immediately after the RST 40. Now an expression like "2"+STR\$ 0.5 is evaluated incorrectly as 0.5; the zero left on the stack displaces the "2" and is treated as a null string. Similarly all the string comparisons can yield incorrect values if the second string takes the form STR\$ x where x is numerically less than 1; e.g. the expression "50"
 Prev: 11733 Up: Map Next: 12171