Reputation: 1
(Shared with the TI-BASIC community because the HP Prime community is near non-existent on Stack Exchange, and because porting programs both ways hasn't been too hard, at least in my experience.)
I am trying to boost my calculators capability by creating a matrix-based arbitrary number library. I have been getting accurate answers until now.
I've been working to create a arbitrary number library to extend the overflow on my HP Prime, as well as adding precision. I have done this by parsing two string inputs into matrices and performing operations on a cell by cell basis, with overflow. Until now it appeared to perform +/-/* operations without issue. During a calculation to probe beyond the calculators default 1x10^500 limit (currently my program theoretically caps at 1x10^3000, with the option of raising that to up to 1x10^81,000). To do this I attempted to calculate 4^4200 * 99^50. The result I received was less than 1*10^223, which I knew couldn't be the correct value. So somewhere it is either multiplying cells wrong, or truncating the input string. If you want to look at this in-calculator and you don't have one, HP offers an official emulator for free off their website. (using Delphi syntax highlighting to approximate HP PPL)
EXPORT BNsto(X,Y)
BEGIN
//Pre−generate Output
MAKEMAT(0,2,1000)▶M3;
MAKEMAT(0,2,1000)▶M4;
//Vectorize X
1▶U;
MAKEMAT(0,2,1000)▶M1;
FOR C FROM 1 TO CEILING(DIM(X)/3) DO
EXPR(RIGHT(X,3))▶M1(1,C);
IF DIM(X)≥3 THEN
LEFT(X,(DIM(X)-3))▶X;
END;
END;
M1▶M4;
FOR C FROM 1 TO 1000 DO
M4(1,C)▶M1(1,(1001-C));
END;
//Vectorize Y
1▶V;
MAKEMAT(0,2,1000)▶M2;
FOR D FROM 1 TO CEILING(DIM(Y)/3) DO
EXPR(RIGHT(Y,3))▶M2(1,D);
IF DIM(Y)≥3 THEN
LEFT(Y,(DIM(Y)-3))▶Y;
END;
END;
M2▶M4;
FOR D FROM 1 TO 1000 DO
M4(1,D)▶M2(1,(1001-D));
END;
END;
////////
EXPORT BNtrim()
BEGIN
M3▶M4;
FOR C FROM 1 TO 1000 DO
M4(1,C)▶M3(1,(1001-C));
END;
0▶Z;
0▶D;
FOR C FROM 1000 DOWNTO 1 DO
IF M3(1,C)+Z=0 THEN
D+1▶D;
ELSE
1▶Z;
END;
END;
REDIM(M3,{1,(1000-D)});
M3▶M4;
FOR C FROM 1 TO (1000-D) DO
M4(1,C)▶M3(1,((1000-D)-C+1));
END;
END;
////////
EXPORT BNmult(X,Y)
BEGIN
0▶Z;
//Vectorize Input
BNsto(X,Y);
//Clear Output
FOR C FROM 1 TO 1000 DO
M3(2,C)▶M3(1,C);
END;
//Perform Operation
FOR B FROM 1000 DOWNTO 1 DO //<-- Where I suspect issues arise.
FOR C FROM 1000 DOWNTO 1 DO
M3(1,C)+Z+(M1(1,B))*(M2(1,C))▶D;
0▶Z;
//Account for Positive Rollover
WHILE D≥1000 DO
EXPR(LEFT(STRING(D),DIM(STRING(D))-3))▶Z;
EXPR(RIGHT(STRING(D),3))▶D;
END;
D▶M3(1,C);
END;
END;
//Trim Output
BNtrim();
END;
Where X is
"448707757012839455309988823384023570217382023410572352132240159311976273559306909949896086662607760278124606679518751885625884533694619507503026349914768426861747593802280773821772416408875901487066526265026305667941615575166174903872068087743676760199083667121277668311584275009665264903864515944617908712723287459232291260129634276229908301402499971955385457162445529951417773148752185812095502631183129165210524830514114465987973781359281956167647888699479090990161019577468495049848196418783654076433180861846461599104044973457213015089019356982008879191317969405874158682767654151166482515723607747513680058428646600294620339178864798770475883170920418838166581453611522008467230703367447366497621385458219132583927289676302395042470581032749514332565175967813899473859769146838779167186771656891644069759727377159974612337367385809154100630846287921465865344914641493458819884053851214622278988653511235185959968366171629847583944618207182864243509174268802129988320467485630854362607420594778603548751141966261652946048159742340561321418878325323461280415496684143870222095726555094800851561934920062077098581053064990873075831889262988863577170685702579901106375917685677127517510854434890252202227632819968882204042209977813155911576322438758839117212133144333475303097541505442870752001891207543717729750807403665780805733139589665408714948547479539969655074797355758413252492746181318963662443777174625555745740037680904238852648585446602157569130784611688080213458299144434782404446632396161494418397414110967220792361627037416963153902049518286576715684058577311870707764077237853902275414358317406584908405498875498704521847342686987573468465859123104573049282333991622834006883804181647516979504674177737103915501496410989112741585083898404719924012433286485556850302897686943639747616443405525997134629249102537302657589689748022067944661365787721410006802753424376253390690455051473511879267686728828040116448789454747991065214975115575618426973514831568007856523214931624053552838679936898072783240150682474408187416275461894645002976300078086846458558958446188233823917017268608126008560374725220271404739531005223228332813444928383618449214304342883329283192522418704865383833918134376657505265608747452128868092817414539130966289955836356699499614565745185823379832016150543419173615945213335586469665533406455394250783877874864459640817970946803811400031942419585406791386620725555528215724935989708661385150080918985335902393064429432671267171655676116126677422777154847606284017929435735485957877715173376"
and Y Is
"6050060671375366504479199680125555354571111154849793880846497346573918278439742113929535410412245001"
the expected output is
2714709153644434292890637136888628957228400268048279162148640553691601004498358288050293961305023875148228273010824422271138903421134733326499044301847851158101848246729046992292909107333444875858017958025203597855055812830986687143052631072076649809056039978122257185656034679528706672846688011536999078089749888678505315971952805072341192056527382788217887418441960382555841614670478228163281677761159417547548554993786592112004501447929755606530404731638799261993116079176299334696481924788634012248288502540328313616013165637320197713118675923899969461180288468550560535099983756260244369896665420990179629898732529665632523546525359883919625736940536257042035390574775059530681917411793233487460031446497457268493630310402289794288468210593375152581738025730273212579346581752210008007711088995071200471248909606299030963613520560331527763906078869065256971415868297652656347226479445032539918934978146316973389307612633359506085000990830697527022193186543224233784549091912007371340295545123367471779533973217465499957522325389970735168749615900461310038733143340874469272137483874894918947851314071067975516772414692577427000418074268390836563034028592944665560388145585108472561417834830343056550158869842789867892951283205318599637205688693751186392554470186022295601201188838042578293880234887854802505071515199429046309269599098886600508634716003172744947894003360097289770901313938320108852484194764220775974932481184202720481525896253015284478662113700091305971042294149676575345050665026564991910889907732476095733839372187514658877115143218505340849650984734829731584436615635605841914987329570724893957162020100083569127335620208593598036108210303683889788488521481074027109888040831533904429548599649450741396493975027952511356433442227794283636988927964009373837222090191465321415588274405013777176974106101478767563894624180901897778292106644360559869302169605249778185968915451466991959084820855332938259956567290576301796233386102937323105206419829161130896230126627709744227818204552832331999487040347791035747832809638334637116619148486300881494277499665632977192468572425238854322142502401261557212067843715468050787934094885241317312473276168439201163382745193921612694138535376704496227953229035057718512597569089476033841199788895923877372266099970306542598120437168891127681001960867994015101157953469132100431547905683909270695201742594193388499848320908562661911425751314810474731727057550449239800848781120949277737382298099496929604849253973414102490047232888258745037182513309284709056190158841222798999721228801879910976211421559678494787414944250436404083973432028138333131476065893686104293376
formatted as a vector with 3 digit cells, the actual output is
2623705611112669690531476608481329088395435490079090713131177118299324844137849203579365903291836640603666
formatted as a vector with 3 digit cells.
Upvotes: 0
Views: 220
Reputation: 1
IT WORKS!
Sort of. The following code allows me to calculate the example and subsequent examples accurately on the virtual. My mistake was stupid and obvious in retrospect; I failed to account for the shift in cells from each subsequent B cycle. Basically, take 123*45 for example, instead of adding 615+4920, I was adding 615+492. Except in my case it was cells of three numbers instead of 1.
EXPORT BNmult(X,Y)
BEGIN
0▶Z;
//Vectorize Input
//Pre−generate Output
MAKEMAT(0,2,2001)▶M3;
MAKEMAT(0,2,2001)▶M4;
//Vectorize X
1▶U;
MAKEMAT(0,2,1000)▶M1;
FOR C FROM 1 TO CEILING(DIM(X)/3) DO
EXPR(RIGHT(X,3))▶M1(1,C);
IF DIM(X)≥3 THEN
LEFT(X,(DIM(X)-3))▶X;
END;
END;
M1▶M4;
FOR C FROM 1 TO 1000 DO
M4(1,C)▶M1(1,(1001-C));
END;
//Vectorize Y
1▶V;
MAKEMAT(0,2,1000)▶M2;
FOR D FROM 1 TO CEILING(DIM(Y)/3) DO
EXPR(RIGHT(Y,3))▶M2(1,D);
IF DIM(Y)≥3 THEN
LEFT(Y,(DIM(Y)-3))▶Y;
END;
END;
M2▶M4;
FOR D FROM 1 TO 1000 DO
M4(1,D)▶M2(1,(1001-D));
END;
//Clear Output
FOR C FROM 1 TO 2001 DO
M3(2,C)▶M3(1,C);
END;
//Perform Operation
FOR B FROM 1000 DOWNTO 1 DO
FOR C FROM 1000 DOWNTO 1 DO
M3(1,(B+C))+Z+(M1(1,B))*(M2(1,C))▶D;
0▶Z;
//Account for Positive Rollover
WHILE D≥1000 DO
EXPR(LEFT(STRING(D),DIM(STRING(D))-3))▶Z;
EXPR(RIGHT(STRING(D),3))▶D;
END;
D▶M3(1,(B+C));
END;
END;
//Trim Output
M3▶M4;
FOR C FROM 1 TO 2001 DO
M4(1,C)▶M3(1,(2002-C));
END;
0▶Z;
0▶D;
FOR C FROM 2001 DOWNTO 1 DO
IF M3(1,C)+Z=0 THEN
D+1▶D;
ELSE
1▶Z;
END;
END;
REDIM(M3,{1,(2001-D)});
M3▶M4;
FOR C FROM 1 TO (2001-D) DO
M4(1,C)▶M3(1,((2002-D)-C));
END;
END;
Now I mentioned it worked on the virtual calculator. Unfortunately, I receive the "Invalid Input" error on the ACTUAL calculator. This means somewhere, it's miscalculating something in the matrices that's intricate enough to not error on the virtual. And since the Virtual is really only for bug testing, the problem remains unsolved.
UPDATE: Program didn't save to the calculator right. Works fine now. Now to cut down on the over two million operations performed each time you want to multiply. Theoretically colDim() can do this, but current efforts haven't proven successful.
Upvotes: 0