********************************************************************* * #10 Convert 128 unsigned integer to display decimal ********************************************************************* * * 1. Load 128 bit unsigned integer to convert in R0-R1. * 2. If high bit on, move 2**127 digits to PD counters. * 3. Turn off high bit so number is divible by 1E19 w/o overflow. * 4. Divide by unsigned 1E19 giving 64 bit remainder and quotent. * 5. Convert unsigned 64 bit remainder and quotent to PD. * 6. Add remainder to low 19 digit PD counter with possible carry. * 7. Add any carry and quotent to high 20 digit PD counter. * 8. Unpack low 19 digit counter with editing to insert commas. * 9. Unpack high 20 digit counter with editing to insert commas. * P10DSH1 ZMFACC CODE,START,NAME='Don Higgins' LA R3,INT128 R3=TABLE OF 128 BIT UNSIGNED INTEGERS LA R4,INTDEC R4=TABLE OF OUTPUT DISPLAY INTEGERS USING INTDECD,R4 LA R5,TOTINTS R5=TOTAL INTEGERS LOOP DS 0H BAS R10,CVTI128 CONVERT 128 BIT INTO TO DISPLAY AHI R3,16 INC INPUT AHI R4,LINTDECD INC OUTPUT BCT R5,LOOP LM R0,R3,=A(INTDEC,LINTDEC,VERDEC,LINTDEC) CLCL R0,R2 BZ VEROK WTO 'VERIFY ERROR - CALCULATED VERSUS EXPECTED DIFFERENCE' B EXIT VEROK DS 0H WTO 'VERIFY OK - CALCULATED EQUALS EXPECTED DISPLAY VALUES' EXIT DS 0H ZMFACC CODE,END ZMFACC INPUT,START INT128 DS 0D TABLE OF 128 BIT UNSIGNED INTS TO CVT DC FL8'0,0' 0 DC FL8'0,1' 1 DC FL8'0,1E18' 10**18 DC FL8'0',X'8AC7230489E80000' 10**19 = 1E18 * 10 VIA MLG DC FL8'0',8X'FF' 2**64-1 DC FL8'1',8X'FF' 2**65-1 DC X'7F',15X'FF' 2**127-1 DC X'FF',15X'FF' 2**128-1 INTEND EQU * TOTINTS EQU (INTEND-INT128)/16 ZMFACC INPUT,END ZMFACC OUTPUT,START DC C'TABLE OF CALCULATED DISPLAY UNSIGNED INTEGERS=' INTDEC EQU * TABLE OF DISPLAY INTEGERS DC ((INTEND-INT128)/16*LINTDECD)C' ' LINTDEC EQU *-INTDEC DC C'TABLE OF EXPECTED DISPLAY UNSIGNED INTEGERS=' * Ref: http://www.newdream.net/~sage/old/numbers/pow2.htm VERDEC DS 0C TABLE OF EXPECTED DECIMAL RESULTS DC C' 0' 0 DC C' 1' 1 DC C' 1,000,000,000,000,000,000' 1E18 DC C' 10,000,000,000,000,000,000' 1E19 DC C' 18,446,744,073,709,551,615' 2**64-1 DC C' 36,893,488,147,419,103,231' 2**65-1 DC C' 170,141,183,460,469,231,731,687,303,715,884,105,727' 2**127-1 DC C' 340,282,366,920,938,463,463,374,607,431,768,211,455' 2**128-1 ZMFACC OUTPUT,END * * CONVERT 128 BIT UNSIGEND INT AT R3 TO DISPLAY AT R4 * CVTI128 DS 0H LMG R0,R1,0(R3) R0-R1=INPUT 128 BIT UNSIGNED INTEGER TMHH R0,X'8000' IF HIGH BIT ON BZ CLEAR NIHH R0,X'7FFF' TURN HIGH BIT OFF ZAP PLOW,PD127L MOVE 2*127 LOW 19 DIGITS ZAP PHIGH,PD127H MOVE 2*127 HIGH 20 DIGITS B DIVIDE CLEAR DS 0H ZAP PLOW,=P'0' ZAP PHIGH,=P'0' DIVIDE DS 0H DLG R0,UG1E19 DIVIDE BY UNSIGNED 64 BIT 1E19 BAS R11,USCVDG CONVERT UNSIGNED REMAINDER TO PD AP PLOW,PWORK ADD REMAINDER TO LOW 19 PD DIGITS TM PLOW,X'01' IF CARRY INTO 20TH DIGIT BZ NOCARRY AP PHIGH,=P'1' ADD 1 TO HIGH 20 DIGITS NOCARRY DS 0H LGR R0,R1 BAS R11,USCVDG CONVERT UNSIGNED QUOTENT TO PD AP PHIGH,PWORK ADD QUOTENT TO HIGH 20 PD DIGITS BZ NOLEAD IF HIGH DIGITS NOT ZERO MVI PLOW,X'01' FORCE LEADING ZEROS FOR LOW DIGITS NOLEAD DS 0H (NOTE 2 DIGIT OVERLAY OF HIGH/LOW) MVC DLOW,MASKL21 MOVE EDIT MASK FOR LOW 19 DIGITS + 2 ED DLOW,PLOW CONVERT LOW 19 DIGITS TO DISPLAY + 2 MVC DHIGH,MASKH21 MOVE EDIT MASK FOR HIGH 20 DIGITS + 1 ED DHIGH,PHIGH CONVERT HIGH 20 DIGITS TO DISPLAY + 1 BR R10 * * CONVERT UNSIGNED 64 BIT R0 TO PL16 PWORK AND EXIT R11 * USCVDG DS 0H TMHH R0,X'8000' IF HIGH BIT ON BZ USCVDGOK NIHH R0,X'7FFF' TURN OFF HIGH BIT CVDG R0,PWORK CONVERT AS POSITIVE 63 BITS AP PWORK,PD2P63 ADD 2**63 FOR HIGH BIT BR R11 USCVDGOK DS 0H CVDG R0,PWORK CONVERT POSITIVE 64 BITS BR R11 PWORK DC PL16'0' WORK AREA FOR CVDG PHIGH DC PL11'0' HIGH 20 DIGITS PLUS 1 PLOW DC PL11'0' LOW 19 DIGITS PLUS 2 FOR CARRY UG1E19 DC X'8AC7230489E80000' UNSIGNED 1E19 (F'1E18' * 10) PD127H DC PL16'17014118346046923173' HIGH 20 DIGITS OF 2*127 PD127L DC PL16'1687303715884105728' LOW 19 DIGITS OF 2*127 PD2P63 DC PL16'9223372036854775808' 2**63 FOR HIGH BIT OF R/Q MASKH21 DC C' ',X'20',C',',6AL1(X'20',X'20',X'20',C','),X'2020' MASKL21 DC C' ',6AL1(X'20',X'20',X'20',C','),X'202120' INTDECD DSECT DHIGH DS C' 0,ZZZ,ZZZ,ZZZ,ZZZ,ZZZ,ZZZ,ZZ' HIGH 20 DIGITS ORG *-3 BACKUP TO OVERLAY FILLER AND CARRY DIGITS DLOW DS C' CCZ,ZZZ,ZZZ,ZZZ,ZZZ,ZZZ,ZZZ' LOW 19 DIGITS LINTDECD EQU *-INTDECD END