MCODE - Prime Twin Finder - RFF (Request For Feedback) « Next Oldest | Next Newest »

 ▼ PeterP Unregistered Posts: 564 Threads: 72 Joined: Sep 2005 07-20-2008, 01:19 PM Hi, As is customary for me when trying to learn a new language, I try writing a prime-finder, prime-twin finder and testing goldbach's conjecture. We already have a very good prime-finder in MCODE (see SANDBOX or the original article from Jason DeLooze in PPCJ V11 N7 p30) so I decided to build a Prime-Twin finder as my second program in MCODE (the first one was the MCODE instruction timer see the discussion here a few weeks back) It would be great to get some feedback and suggestions from the MCODE guru's around on how to improve the routine below as well as pointing out errors and mistakes I am sure I have made plenty off. The listing can be copied into a .src file and can be directly assembled with a41, linked with l41 (just need a simple .lnk file which tells is where to link it to, I used page B) and then used with m41. This SDK41 from Warren is truly amazing! ```Name: PTWIN Purpose: Find the next prime twin numbers (p,p+2) greater than X. Input: Starting number for the search in X Output: p+2 in X, X in L, rest undisturbed. This allows for quick consecutive searches Range: 1-1e10. ``` (well, actually the largest legal prime twin is 9,999,999,701 / 703 but following a note with regards to the cold start constant in the VASM from HPs programmer 'for now I leave well enough alone') I have not amended the range testing routine. It was however quite fun to use the program to find that number as I did not find a web-page which has such large primes. Using Warren's simulator PTWIN finds those high prime-twins within a couple of minutes actually...) ```Name:FFACT Purpose: Find the smallest prime factor of the number in X. PTWIN uses FFACT to test for prime-number. Input: Number in X, 1<=X<1e10 Output: Stack copied (Z->T,Y->Z,X->Y, X-L), X has smallest prime factor. ``` One question for example is with regards to using a main-frame entry-point for copying the stack upwards. It would seem that such a entry-point must exist but I did not find a reference in either Ken's book nor the HEPAX manual. Any and all comments would be much appreciated. Thanks! Peter ```* PPPRIM.SRC * Assembled by A41 * Sun Jul 20 13:20:54 2008 ;***************** Start of PPPRIM rom **************** .TITLE "PPPRIM" .JDA .EQU [PCTOC] 00D7 ;********************************** ;* FAT for PPPRIM ROM * ;********************************** 0000 001 XROM 1 ;XROM number 0001 003 FCNS 3 ;Header + 1 function 0002 000088 DEFR4K [Header] 0088 ;first executable of header 0004 00008E DEFR4K [FFACT] 008E 0006 001028 DEFR4K [PTWIN] 0128 0008 000 NOP ;FAT termination 0009 000 NOP ;FAT termination ;*********************************** .FILLTO 0081 ;******** Start of Code ************ ;**** Header .NAME "PPPRIM" *0082 08D #08D ; "M" *0083 009 #009 ; "I" *0084 012 #012 ; "R" *0085 010 #010 ; "P" *0086 010 #010 ; "P" *0087 010 #010 ; "P" 0088 3E0 [Header] RTN ;********************************************************************* ;FFACT is the PRIM function adapted for PTWIN. ;Gives First Factor which is the number itself if prime ; [FFACT] entry point does full check of range, div by 2 etc - Flag 5 is set! ; [PPRIM] entry point for PTWIN does no check of range and no div by 2 .NAME "FFACT" *0089 094 #094 ; "T" *008A 003 #003 ; "C" *008B 001 #001 ; "A" *008C 006 #006 ; "F" *008D 006 #006 ; "F" 008E 078 [FFACT] READ 1(z) 008F 028 WRIT 0(T) 0090 0B8 READ 2(y) 0091 068 WRIT 1(z) 0092 0F8 READ 3(x) 0093 0A8 WRIT 2(y) 0094 128 WRIT 4(L) ;---------------------- Make sure starting point is less than 1e10 0095 2A0 SETDEC 0096 2FE ?C#0 MS 0097 033 JNC +6 009D 0098 23E C=C+1 MS 0099 389052 (adatp) ?NCGO [ERRAD] 14E2 009B 0B50A2 (derrp) ?NCGO [ERRDE] 282D 009D 2EE ?C#0 ALL 009E 3EB JNC (derrp) -3 009B 009F 2F6 ?C#0 XS 00A0 3DF JC (derrp) -5 009B 00A1 31C (cklpp) R= 1 00A2 2E2 ?C#0 @R 00A3 3C7 JC (derrp) -8 009B 00A4 10E A=C ALL 00A5 3EE (shflpp) LSHFA ALL 00A6 386 RSHFA S&X 00A7 35A ?A#0 M 00A8 023 JNC [Chk1] +4 00AC 00A9 1A6 A=A-1 S&X 00AA 3BF JC (cklpp) -9 00A1 00AB 3D3 JNC (shflpp) -6 00A5 ;---------------------- Check if it is 1 00AC 0F8 [Chk1] READ 3(x) 00AD 0AE A<>C ALL 00AE 04E C=0 ALL 00AF 35C R= 12 00B0 050 LD@R 1 00B1 36E ?A#C ALL 00B2 07B JNC [ExitP] +15 00C1 ;---------------------- Check division by 2 00B3 0BA [Chk2] A<>C M ;A has number, now C has Mant, and A Exp 00B4 2FC (shlp2) RCR 13 ;de facto a LSHF C 00B5 1A6 A=A-1 S&X 00B6 3F3 JNC (shlp2) -2 00B4 00B7 2FC RCR 13 ;first digit was moved to R=13 and now to C[0] 00B8 3D8 C<>ST ;move it into ST 00B9 04E C=0 ALL ;Set up correct exit if divisible by 2 00BA 35C R= 12 ;by storing 2 in B 00BB 090 LD@R 2 00BC 0EE B<>C ALL 00BD 088 SETF 5 ;Force setting of flag 5 - we are in Prime only mode 00BE 38C ?FSET 0 ;if the first flag not set, we have even number 00BF 02B JNC [ExitNP] +5 00C4 00C0 053 JNC [PPRIM] +10 00CA ;with Flag 5 set ;---------------------------------------- Exit Functions 00C1 04E [ExitP] C=0 ALL ;we have a prime; C=0 00C2 260 SETHEX ;to save jump distance in PTWIN loop 00C3 3E0 RTN 00C4 0EE [ExitNP] C<>B ALL ;we don't have a prime. C has the first divisor from B 00C5 260 SETHEX ;to save jump distance in PTWIN loop 00C6 08C ?FSET 5 ;are we in prime only mode? 00C7 3A0 ?NCRTN ;no, just return 00C8 0E8 WRIT 3(x) ;yes, write it into X reg and then return 00C9 3E0 RTN ;---------------------- Start of PRIME test for PTWIN 00CA 0F8 [PPRIM] READ 3(X) 00CB 2A0 SETDEC 00CC 2F9060 [SQREP] ?NCXQ [SQR10] 18BE ;get SQR(x) 00CE 03C RCR 3 ;move S&X into front 00CF 070 N=C ;save SQR in N 00D0 1A0 A=B=C=0 00D1 25C R= 9 ;Load Divisor Pattern 00D2 190 LD@R 6 00D3 090 LD@R 2 00D4 190 LD@R 6 00D5 110 LD@R 4 00D6 090 LD@R 2 00D7 110 LD@R 4 00D8 090 LD@R 2 00D9 110 LD@R 4 00DA 090 LD@R 2 00DB 090 LD@R 2 00DC 33C RCR 1 00DD 158 M=C ;Store into N 00DE 0F8 READ 3(x) 00DF 0AE A<>C ALL ;Store X in A 00E0 35C R= 12 00E1 0D0 LD@R 3 00E2 0EE C<>B ALL ;Store 3 (first divisor) in B 00E3 35C R= 12 00E4 04E [ploop] C=0 ALL 00E5 186 A=A-B S&X ;move S&X into C to keep track of 00E6 0E6 C<>B S&X 00E7 1BC RCR 11 00E8 0A6 A<>C S&X 00E9 18E (sub) A=A-B ALL ;subtract divisor in B repeatedly 00EA 3FB JNC (sub) -1 00E9 00EB 12E A=A+B ALL ;deal with underflow 00EC 3EE LSHFA ALL 00ED 266 C=C-1 S&X 00EE 3DB JNC (sub) -5 00E9 ;rinse and repeat 00EF 03C RCR 3 00F0 0E6 C<>B S&X 00F1 34E ?A#0 ALL ;if A=0 then it is not prime 00F2 293 JNC [ExitNP] -46 00C4 00F3 198 C=M ;otherwise, get pattern from M for next divisor 00F4 33C RCR 1 00F5 2E2 ?C#0 @R ;if 0, wrap around 00F6 017 JC (bis0) +2 00F8 00F7 17C RCR 6 ;wraparound 00F8 00E (bis0) A=0 ALL 00F9 102 A=C @R ;get next number to calc next divisor 00FA 12E A=A+B ALL ;calc next divisor 00FB 35E ?A#0 MS ;overflow? 00FC 033 JNC (noovfl) +6 0102 00FD 3E6 LSHFA S&X ;deal with overflow 00FE 38E RSHFA ALL 00FF 166 A=A+1 S&X 0100 3D4 R=R-1 0101 33C RCR 1 0102 158 (noovfl) M=C 0103 08E B=A ALL ;move new divisor into B 0104 0B0 C=N ;now get SQR 0105 0AE A<>C ALL 0106 03C RCR 3 0107 30E ?A=10 and n<1e10 it gives the next prime-twins (p,p+2) ;the function places p+2 in x so that it can be rerun immediately for the next pai ;the largest ptwin that it can calculate is (9,999,999,701,9,999,999,703) ;so to be perfect the test for the starting point should be adjusted accordingly... ;starting numbers <10 all give (11,13) as the first pair .NAME "PTWIN" *0123 08E #08E ; "N" *0124 009 #009 ; "I" *0125 017 #017 ; "W" *0126 014 #014 ; "T" *0127 010 #010 ; "P" 0128 2A0 [PTWIN] SETDEC ;---------------------- Make sure starting point is less than 1e10 0129 0F8 READ 3(x) 012A 128 WRIT 4(L) 012B 2FE ?C#0 MS 012C 033 JNC +6 0132 012D 23E C=C+1 MS 012E 389052 (adat) ?NCGO [ERRAD] 14E2 0130 0B50A2 (derr) ?NCGO [ERRDE] 282D 0132 2EE ?C#0 ALL 0133 3EB JNC (derr) -3 0130 0134 2F6 ?C#0 XS 0135 3DF JC (derr) -5 0130 0136 31C (cklp) R= 1 0137 2E2 ?C#0 @R 0138 3C7 JC (derr) -8 0130 0139 10E A=C ALL 013A 3EE (shflp) LSHFA ALL 013B 386 RSHFA S&X 013C 35A ?A#0 M 013D 023 JNC (go) +4 0141 013E 1A6 A=A-1 S&X 013F 3BF JC (cklp) -9 0136 0140 3D3 JNC (shflp) -6 013A ;---------------------- Calc Base number as #-(#Mod30 +1), Min Startnumber is 29 0141 1A0 (go) A=B=C=0 ;clean slate 0142 0F8 READ 3(x) ;Calc #Mod30 and store #-#MOD30-1 in x as new base number 0143 128 WRIT 4(L) ;put it in LastX 0144 0AE A<>C ALL ;save it into A 0145 1A6 A=A-1 S&X ;chec if it is at least >=10 0146 14F JC [MinST] +41 016F ;Goto MinStart = 11 0147 166 A=A+1 S&X 0148 35C R= 12 0149 0D0 LD@R 3 ;Load 30 014A 226 C=C+1 S&X 014B 070 N=C 014C 171064 ?NCXQ [MOD10] 195C ;C=AModC = #Mod30 014E 070 N=C ;save #Mod30 into N 014F 0AE A<>C ALL ;prep for MF [AddOne] 0150 08E B=A ALL 0151 001060 ?NCXQ [ADDONE] 1800 ; disturbs M 0153 2BE C=-C-1 MS 0154 0AE A<>C ALL ;A=-(#Mod30+1) 0155 0F8 READ 3(x) 0156 0AE A<>C ALL ;C=-(#Mod30+1), A=# 0157 01D060 ?NCXQ [AD2_10] 1807 ;C=A+C; disturbs M 0159 0E8 WRIT 3(x) ;this is our base # BN ;------------------------ Calc actual start number which is BN + 12, 18 or 20 015A 0B0 [CASN] C=N ;now lets find out where to actually start looking for twins 015B 266 C=C-1 S&X ;if <=10 then we start at BN + 12 015C 12F JC (Ad12) +37 0181 015D 35C R= 12 015E 262 C=C-1 @R ;it could be 10 or 11 015F 2FA ?C#0 M 0160 10B JNC (Ad12) +33 0181 ;it was 10 0161 2E2 ?C#0 @R ;only true if >=20 0162 0A7 JC (Ad30) +20 0176 0163 3D4 R=R-1 0164 262 C=C-1 @R ;was it 11? 0165 2FA ?C#0 M 0166 0DB JNC (Ad12) +27 0181 ;it was 11 indeed 0167 2FC RCR 13 ;as S&X= 0, this is de facto a LSHF C 0168 0AE A<>C ALL 0169 04E C=0 ALL 016A 35C R= 12; 016B 1D0 LD@R 7 ;<(11+7=18)? 016C 1DA A=A-C M 016D 077 JC (Ad18) +14 017B ;otherwise it is Ad30 016E 043 JNC (Ad30) +8 0176 ;Add 30 ;---------------------- Min Startnumber is 11 016F 35C [MinST] R= 12 0170 050 LD@R 1 0171 050 LD@R 1 0172 226 C=C+1 S&X 0173 0E8 WRIT 3(x) 0174 308 SETF 1 ;we want to start at [FST] 0175 0F3 JNC [Exit] +30 0193 ;---------------------- Ad 12, 18 or 30 to Startnumber 0176 008 (Ad30) SETF 3 ;we want to start at [TRD] 0177 04E C=0 ALL ;Add 30 to BN 0178 35C R= 12 0179 0D0 LD@R 3 017A 063 JNC [CSN] +12 0186 ;Calc Start Number 017B 208 (Ad18) SETF 2 ;we want to start at [SND] 017C 04E C=0 ALL 017D 35C R= 12 017E 050 LD@R 1 017F 210 LD@R 8 0180 033 JNC [CSN] +6 0186 ;Calc Start Number 0181 308 (Ad12) SETF 1 ;we want to start at [FST] 0182 04E C=0 ALL 0183 35C R= 12 0184 050 LD@R 1 0185 090 LD@R 2 0186 226 [CSN] C=C+1 S&X ;Calc Start Number 0187 0AE A<>C ALL 0188 0F8 READ 3(x) ;BaseNumber BN 0189 01D060 ?NCXQ [AD2_10] 1807 ;StartNumber = BN + addon 018B 0E8 WRIT 3(x) 018C 260 SETHEX ;?NCXQREL needs HEX mode 018D 30C ?FSET 1 ;we want to start at FST - Start = BN + 12 018E 13F JC [FST] +39 01B5 018F 20C ?FSET 2 ;we want to start at SND - Start = BN + 12+6 = BN+18 0190 177 JC [SND] +46 01BE 0191 00C ?FSET 3 ;we want to start at TRD - Start = BN + 12+6+12 = BN+30 0192 1A7 JC [TRD] +52 01C6 0193 0C3 [Exit] JNC [START] +24 01AB ;-------------------------------------- End of Finding Starting Number --------------------------------------- ;----------------------------- We Found a PTWIN, placed here to make jump-distances <64 0194 1B0 [FPT] POPADR ;we found a PTWIN it is in X 0195 04E C=0 ALL 0196 358 ST=C 0197 3E0 RTN ;----------------------------- Check if Prime +2 is also Prime - placed here so that JC can get to it within 64 words 0198 2A0 [C+2] SETDEC 0199 0F8 READ 3(x) 019A 268 WRIT 9(Q) 019B 0AE A<>C ALL 019C 04E C=0 ALL 019D 35C R= 12 019E 090 LD@R 2 019F 01D060 ?NCXQ [AD2_10] 1807 01A1 0E8 WRIT 3(x) 01A2 260 SETHEX 01A3 37903C0CA ?NCXQREL [PPRIM] 00CA 01A6 2EE ?C#0 ALL ;Did we find a prime number? 01A7 36B JNC [FPT] -19 0194 ;Yes, exit the program 01A8 278 READ 9(Q) ;No, return to main loop 01A9 0E8 WRIT 3(x) 01AA 3E0 RTN ;------------------------------------------------------------------------------------------------------------------------- ;-------------------------------------- Start of PTWIN Searching Loop ------------------------------------------ 01AB 260 [START] SETHEX 01AC 37903C0CA ?NCXQREL [PPRIM] 00CA ;PRIM finishes in HEX mode 01AF 2EE ?C#0 ALL ;Did we find a prime number? 01B0 37903C198 ?NCXQREL [C+2] 0198 ;Yes, so also check #+2 01B3 308 SETF 1 ;No, lets move on to next. Let [+12] we are [FST] 01B4 0D3 JNC [N+12] +26 01CE ;Add 12 to current number in X 01B5 304 [FST] CLRF 1 01B6 37903C0CA ?NCXQREL [PPRIM] 00CA 01B9 2EE ?C#0 ALL ;Did we find a prime number? 01BA 37903C198 ?NCXQREL [C+2] 0198 ;Yes, so also check #+2 01BD 14B JNC [N+6] +41 01E6 ;No, lets move to next 01BE 37903C0CA [SND] ?NCXQREL [PPRIM] 00CA 01C1 2EE ?C#0 ALL ;Did we find a prime number? 01C2 37903C198 ?NCXQREL [C+2] 0198 ;Yes, so also check #+2 01C5 04B JNC [N+12] +9 01CE ;No, lets move to next 01C6 37903C0CA [TRD] ?NCXQREL [PPRIM] 00CA 01C9 2EE ?C#0 ALL ;Did we find a prime number? 01CA 37903C198 ?NCXQREL [C+2] 0198 ;Yes, so also check #+2 01CD 2F3 JNC [START] -34 01AB ;No, so lets keep looking ;------------------------------- End of PTWIN Searching Loop ;-------- Add 12 to X 01CE 2A0 [N+12] SETDEC 01CF 0F8 READ 3(x) ; Add 12 to current number in Reg x 01D0 01C R= 3 01D1 2E2 (sffd) ?C#0 @R 01D2 01F JC (ffd) +3 01D5 01D3 3DC R=R+1 01D4 3EB JNC (sffd) -3 01D1 01D5 3DC (ffd) R=R+1 01D6 0AE A<>C ALL 01D7 04E C=0 ALL 01D8 050 LD@R 1 01D9 090 LD@R 2 01DA 14E A=A+C ALL 01DB 35E ?A#0 MS 01DC 023 JNC (novfl) +4 01E0 01DD 166 A=A+1 S&X 01DE 3E6 LSHFA S&X 01DF 38E RSHFA ALL 01E0 0AE (novfl) A<>C ALL 01E1 0E8 WRIT 3(x) 01E2 260 SETHEX ;Set HEX mode for ?NCXQREL that comes in main loop 01E3 30C ?FSET 1 ;Did we come from First ? 01E4 28F JC [FST] -47 01B5 ;Yes 01E5 30B JNC [TRD] -31 01C6 ;No, it was the last one ;-------- Add 6 to X 01E6 2A0 [N+6] SETDEC 01E7 0F8 READ 3(x) ;Add 6 to current number in Reg x 01E8 01C R= 3 01E9 2E2 (sffd6) ?C#0 @R 01EA 01F JC (ffd6) +3 01ED 01EB 3DC R=R+1 01EC 3EB JNC (sffd6) -3 01E9 01ED 0AE (ffd6) A<>C ALL 01EE 04E C=0 ALL 01EF 190 LD@R 6 01F0 14E A=A+C ALL 01F1 35E ?A#0 MS 01F2 023 JNC (novfl6) +4 01F6 01F3 166 A=A+1 S&X 01F4 3E6 LSHFA S&X 01F5 38E RSHFA ALL 01F6 0AE (novfl6) A<>C ALL 01F7 0E8 WRIT 3(x) 01F8 260 SETHEX ;Set HEX mode for ?NCXQREL that comes in main loop 01F9 22B JNC [SND] -59 01BE ;============================================================== * * GLOBAL SYMBOLS * SYMBOL VALUE TYPE REFERENCES * [C+2] 0198 REL 01B0 01BA 01C2 01CA * [CASN] 015A REL * [CSN] 0186 REL 017A 0180 * [Chk1] 00AC REL 00A8 * [Chk2] 00B3 REL * [ExitNP] 00C4 REL 00BF 00F2 * [ExitP2] 010C REL 0108 * [ExitP] 00C1 REL 00B2 * [Exit] 0193 REL 0175 * [FFACT] 008E REL 0004 * [FPT] 0194 REL 01A7 * [FST] 01B5 REL 018E 01E4 * [Header] 0088 REL 0002 * [MinST] 016F REL 0146 * [N+12] 01CE REL 01B4 01C5 * [N+6] 01E6 REL 01BD * [PCTOC] 00D7 ABS * [PPRIM] 00CA REL 00C0 01A3 01AC 01B6 01BE 01C6 * [PTWIN] 0128 REL 0006 * [SND] 01BE REL 0190 01F9 * [SQREP] 00CC REL * [START] 01AB REL 0193 01CD * [TRD] 01C6 REL 0192 01E5 * [ploop] 00E4 REL 010B * * LOCAL SYMBOLS * SYMBOL VALUE TYPE REFERENCES * (Ad12) 0181 REL 015C 0160 0166 * (Ad18) 017B REL 016D * (Ad30) 0176 REL 0162 016E * (adat) 012E REL * (adatp) 0099 REL * (bis0) 00F8 REL 00F6 * (cklp) 0136 REL 013F * (cklpp) 00A1 REL 00AA * (derr) 0130 REL 0133 0135 0138 * (derrp) 009B REL 009E 00A0 00A3 * (ffd) 01D5 REL 01D2 * (ffd6) 01ED REL 01EA * (go) 0141 REL 013D * (noovfl) 0102 REL 00FC * (novfl) 01E0 REL 01DC * (novfl6) 01F6 REL 01F2 * (sffd) 01D1 REL 01D4 * (sffd6) 01E9 REL 01EC * (shflp) 013A REL 0140 * (shflpp) 00A5 REL 00AB * (shlp2) 00B4 REL 00B6 * (sub) 00E9 REL 00EA 00EE * * EXTERNAL REFERENCES * SYMBOL REFERENCED AT * * MAINFRAME REFERENCES * SYMBOL VALUE REFERENCES * [AD2_10] 1807 0157 0189 019F * [ADDONE] 1800 0151 * [ERRAD] 14E2 0099 012E * [ERRDE] 282D 009B 0130 * [MOD10] 195C 014C * [SQR10] 18BE 00CC * * A41: 0 WARNINGS(S) * A41: 0 ERROR(S) * END ```

 Possibly Related Threads… Thread Author Replies Views Last Post HP-41 MCODE: The Last Function - at last! Ángel Martin 0 1,052 11-08-2013, 05:11 AM Last Post: Ángel Martin Prime feature request Stefan Dröge (Germany) 0 1,017 11-06-2013, 11:06 AM Last Post: Stefan Dröge (Germany) request M.E. pac for HP-67/97 wallet cover scan Ignacio Sánchez 0 1,073 11-06-2013, 09:36 AM Last Post: Ignacio Sánchez Reig HP-Prime Polynomials: User Guide and Request CompSystems 4 2,148 09-30-2013, 09:48 PM Last Post: Han HP Prime "Notes" feature request Charles Bennett 0 911 09-27-2013, 12:14 PM Last Post: Charles Bennett [REQUEST] Your "Prime" Conference Questions Tim Wessman 9 2,827 09-22-2013, 05:34 AM Last Post: Giancarlo [HP-Prime xcas] operations with complex numbers + BUGs + Request CompSystems 9 3,463 09-08-2013, 10:40 PM Last Post: CompSystems [HP-Prime xCAS] Review Polynomial Tools + BUGs + Request CompSystems 0 965 09-05-2013, 12:53 PM Last Post: CompSystems [HP-Prime] Request: New command for CAS (EvalStep) CompSystems 4 1,764 09-04-2013, 09:33 AM Last Post: Eddie W. Shore [HP Prime] Request: re-execute history like CASIO classPAD serie 300/400 CompSystems 1 1,338 09-03-2013, 02:47 PM Last Post: CompSystems

Forum Jump: