Long multiplication: Difference between revisions

→‎{{header|PL/M}}: Parameters which are arrays have to be passed as pointers in real PL/M
(Added PL/M)
(→‎{{header|PL/M}}: Parameters which are arrays have to be passed as pointers in real PL/M)
Line 4,147:
/* element 0 should contain 0 if the number is positive, 1 if negative */
/* External I/O routines */
WRITE$STRING: PROCEDURE( S ) EXTERNAL; DECLARE S POINTER; END WRITE$STRING;
WRITE$CHAR: PROCEDURE( C ) EXTERNAL; DECLARE C BYTE; END WRITE$CHAR;
WRITE$NL: PROCEDURE EXTERNAL; END WRITE$NL;
/* End external routines */
DECLARE DIGIT$BASE LITERALLY '10';
Line 4,157:
/* returns the position of the highest non-zero digit of the large */
/* integer a with n digits */
HIGHEST$NONZERO$DIGIT$POSITION: PROCEDURE( A$PTR, N ) BYTE;
DECLARE A$PTR LARGE$INTEGER POINTER;
DECLARE N BYTE;
DECLARE A BASED A$PTR LARGE$INTEGER;
DECLARE AMAX BYTE;
AMAX = N;
Line 4,168 ⟶ 4,169:
/* is added to c, starting from start */
/* overflow is ignored */
MULTIPLY$ELEMENT: PROCEDURE( A, B$PTR, C$PTR, START );
DECLARE ( B$PTR, C$PTR ) LARGE$INTEGERPOINTER;
DECLARE ( A, START ) BYTE;
DECLARE ( CDIGIT,B CARRY,BASED BPOSB$PTR, CPOSC BASED C$PTR ) BYTE LARGE$INTEGER;
DECLARE ( CDIGIT, CARRY, BPOS, CPOS ) BYTE;
CARRY = 0;
CPOS = START;
DO BPOS = 1 TO HIGHEST$NONZERO$DIGIT$POSITION( B$PTR, DIGIT$COUNT - START );
CDIGIT = C( CPOS ) + ( A * B( BPOS ) ) + CARRY;
IF CDIGIT < DIGIT$BASE THEN CARRY = 0;
Line 4,189 ⟶ 4,191:
/* implements long multiplication, c is set to a * b */
/* c can be the same array as a or b */
LONG$MULTIPLY: PROCEDURE( A$PTR, B$PTR, C$PTR );
DECLARE ( A$PTR, B$PTR, C$PTR ) LARGE$INTEGER POINTER;
DECLARE MRESULT( A BASED LARGEA$INTEGER;PTR
DECLARE RPOS , BYTE;B BASED B$PTR
, C BASED C$PTR
) LARGE$INTEGER;
DECLARE MRESULT LARGE$INTEGER;
DECLARE RPOS BYTE;
/* the result will be computed in mResult, allowing a or b to be c */
DO RPOS = 1 TO DIGIT$COUNT - 1; MRESULT( RPOS ) = 0; END;
/* multiply and add each digit to the result */
DO RPOS = 1 TO HIGHEST$NONZERO$DIGIT$POSITION( A$PTR, DIGIT$COUNT - 1 );
IF A( RPOS ) <> 0 THEN DO;
CALL MULTIPLY$ELEMENT( A( RPOS ), B$PTR, @MRESULT, RPOS );
END;
END;
Line 4,206 ⟶ 4,212:
END;
/* writes the decimal value of a large integer a with n digits */
WRITE$LARGE$INTEGER: PROCEDURE( A$PTR );
DECLARE A$PTR LARGE$INTEGERPOINTER;
DECLARE A BASED A$PTR LARGE$INTEGER;
DECLARE ( AMAX, APOS ) BYTE;
AMAX = HIGHEST$NONZERO$DIGIT$POSITION( A$PTR, DIGIT$COUNT - 1 );
IF AMAX < 1 THEN CALL WRITE$CHAR( '0' );
ELSE DO;
Line 4,231 ⟶ 4,238:
PWR = 1;
DO WHILE PWR < 64;
CALL LONG$MULTIPLY( @TWOTO64, @TWOTO64, @TWOTO64 );
PWR = PWR + PWR;
END;
/* construct 2^128 */
CALL LONG$MULTIPLY( @TWOTO64, @TWOTO64, @TWOTO128 );
CALL WRITE$STRING( @( '2^128: ', 0 ) );
CALL WRITE$LARGE$INTEGER( @TWOTO128 );
CALL WRITE$NL();
END MAIN;
3,044

edits