Prev: 2DD5 Up: Map Next: 2F8B
2DE3: 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 2DE3 RST \$28 Use the calculator. 2DE4 DEFB \$31 duplicate: x, x 2DE5 DEFB \$36 less_0: x, (1/0) Logical value of x. 2DE6 DEFB \$00,\$0B jump_true to PF_NEGTVE: x 2DE8 DEFB \$31 duplicate: x, x 2DE9 DEFB \$37 greater_0: x, (1/0) Logical value of x. 2DEA DEFB \$00,\$0D jump_true to PF_POSTVE: x Hereafter x'=ABS x. 2DEC DEFB \$02 delete: - 2DED DEFB \$38 end_calc: - 2DEE LD A,"0" Enter the character code for '0'. 2DF0 RST \$10 Print the '0'. 2DF1 RET Finished as the 'last value' is zero. PF_NEGTVE 2DF2 DEFB \$2A abs: x' x'=ABS x. 2DF3 DEFB \$38 end_calc: x' 2DF4 LD A,"-" Enter the character code for '-'. 2DF6 RST \$10 Print the '-'. 2DF7 RST \$28 Use the calculator again. PF_POSTVE 2DF8 DEFB \$A0 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. 2DF9 DEFB \$C3,\$C4,\$C5 2DFC DEFB \$02 delete: The stack is cleared, except for x'. 2DFD DEFB \$38 end_calc: x' 2DFE EXX HL', which is used to hold calculator offsets (e.g. for 'STR\$'), is saved on the machine stack. 2DFF PUSH HL 2E00 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 2E01 RST \$28 Use the calculator again. 2E02 DEFB \$31 duplicate: x', x' 2E03 DEFB \$27 int: x', INT (x')=i 2E04 DEFB \$C2 st_mem_2: (i is stored in mem-2). 2E05 DEFB \$03 subtract: x'-i=f 2E06 DEFB \$E2 get_mem_2: f, i 2E07 DEFB \$01 exchange: i, f 2E08 DEFB \$C2 st_mem_2: (f is stored in mem-2). 2E09 DEFB \$02 delete: i 2E0A DEFB \$38 end_calc: i 2E0B LD A,(HL) Is i a small integer (first byte zero) i.e. is ABS i<=65535? 2E0C AND A 2E0D JR NZ,PF_LARGE Jump if it is not. 2E0F CALL INT_FETCH i is copied to DE (i, like x', >=0). 2E12 LD B,\$10 B is set to count 16 bits. 2E14 LD A,D D is copied to A for testing: is it zero? 2E15 AND A 2E16 JR NZ,PF_SAVE Jump if it is not zero. 2E18 OR E Now test E. 2E19 JR Z,PF_SMALL Jump if DE is zero: x is a pure fraction. 2E1B LD D,E Move E to D and set B for 8 bits: D was zero and E was not. 2E1C LD B,\$08 PF_SAVE 2E1E PUSH DE Transfer DE to DE', via the machine stack, to be moved into the print buffer at PF_BITS. 2E1F EXX 2E20 POP DE 2E21 EXX 2E22 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 2E24 RST \$28 i (i=zero here) 2E25 DEFB \$E2 get_mem_2: i, f 2E26 DEFB \$38 end_calc: i, f Note that the stack is now unbalanced. An extra byte 'DEFB +02, delete' is needed immediately after the RST \$28. 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: 2DD5 Up: Map Next: 2F8B