RosettaCodeData/Task/Arithmetic-derivative/PL-M/arithmetic-derivative.plm

67 lines
2.3 KiB
Plaintext

100H: /* ARITHMETIC DERIVATIVE - BASED ON THE BASIC SAMPLE */
/* RETURNS TRUE IF A < B, FALSE OTHERWISE WITH A AND B TREATED AS SIGNED */
SIGNED$LT: PROCEDURE( A, B )BYTE;
DECLARE ( A, B ) ADDRESS;
IF ( A + 32768 ) < ( B + 32768 ) THEN RETURN 0FFH; ELSE RETURN 0;
END SIGNED$LT ;
/* RETURNS A / B WITH A AND B TREATED AS SIGNED */
SIGNED$DIV: PROCEDURE( AIN, BIN )ADDRESS;
DECLARE ( AIN, BIN )ADDRESS;
DECLARE ( A, B, SIGN )ADDRESS;
SIGN = 1;
A = AIN;
B = BIN;
IF SIGNED$LT( A, 0 ) THEN DO;
SIGN = - SIGN;
A = - A;
END;
IF SIGNED$LT( B, 0 ) THEN DO;
SIGN = - SIGN;
B = - B;
END;
RETURN ( A / B ) * SIGN;
END SIGNED$DIV ;
/* CP/M BDOS SYSTEM CALL AND I/O ROUTINES */
BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5; END;
PR$CHAR: PROCEDURE( C ); DECLARE C BYTE; CALL BDOS( 2, C ); END;
PR$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S ); END;
PR$NL: PROCEDURE; CALL PR$CHAR( 0DH ); CALL PR$CHAR( 0AH ); END;
PR$SIGNED$NUMBER: PROCEDURE( N ); /* PRINTS A SIGNED NUMBER */
DECLARE N ADDRESS;
DECLARE V ADDRESS, N$STR ( 9 )BYTE, W BYTE;
IF SIGNED$LT( N, 0 ) THEN V = - N; ELSE V = N;
DO W = 0 TO LAST( N$STR ); N$STR( W ) = ' '; END;
W = LAST( N$STR );
N$STR( W ) = '$';
N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
DO WHILE( ( V := V / 10 ) > 0 );
N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
END;
IF SIGNED$LT( N, 0 ) THEN N$STR( W := W - 1 ) = '-';
CALL PR$STRING( .N$STR );
END PR$SIGNED$NUMBER;
/* TASK */
DECLARE ( C, N, L, F, Z ) ADDRESS;
DO C = 1 TO 200;
N = C - 100;
L = 0; F = 3; IF SIGNED$LT( N, 0 ) THEN Z = - N; ELSE Z = N;
DO WHILE Z >= 2;
DO WHILE Z MOD 2 = 0; L = L + SIGNED$DIV( N, 2 ); Z = Z / 2; END;
IF F <= Z THEN DO;
DO WHILE Z MOD F = 0; L = L + SIGNED$DIV( N, F ); Z = Z / F; END;
F = F + 2;
END;
END;
CALL PR$SIGNED$NUMBER( L );
IF C MOD 10 = 0 THEN CALL PR$NL;
END;
EOF