使用基于矩阵的任意数库的乘法 (HP Prime)
Multiplication Using Matrix Based Arbitrary Number Library (HP Prime)
(与 TI-BASIC 社区共享,因为 HP Prime 社区在 Stack Exchange 上几乎不存在,并且因为双向移植程序并不难,至少以我的经验而言。)
我试图通过创建一个基于矩阵的任意数字库来提高我的计算器能力。到目前为止,我一直在得到准确的答案。
我一直在努力创建一个任意数字库来扩展我的 HP Prime 上的溢出,并增加精度。我通过将两个字符串输入解析为矩阵并在逐个单元格的基础上执行操作(溢出)来完成此操作。到目前为止,它似乎可以毫无问题地执行 +/-/* 操作。在计算期间探测超出计算器默认 1x10^500 限制(目前我的程序理论上上限为 1x10^3000,可以选择将其提高到 1x10^81,000)。为此,我尝试计算 4^4200 * 99^50。我收到的结果小于 1*10^223,我知道这不是正确的值。所以在某个地方它要么错误地乘以单元格,要么截断输入字符串。如果你想看看这个内置计算器,但你没有,惠普在他们的网站上免费提供了一个官方模拟器。
(使用 Delphi 语法突出显示近似 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;
其中 X 是
"448707757012839455309988823384023570217382023410572352132240159311976273559306909949896086662607760278124606679518751885625884533694619507503026349914768426861747593802280773821772416408875901487066526265026305667941615575166174903872068087743676760199083667121277668311584275009665264903864515944617908712723287459232291260129634276229908301402499971955385457162445529951417773148752185812095502631183129165210524830514114465987973781359281956167647888699479090990161019577468495049848196418783654076433180861846461599104044973457213015089019356982008879191317969405874158682767654151166482515723607747513680058428646600294620339178864798770475883170920418838166581453611522008467230703367447366497621385458219132583927289676302395042470581032749514332565175967813899473859769146838779167186771656891644069759727377159974612337367385809154100630846287921465865344914641493458819884053851214622278988653511235185959968366171629847583944618207182864243509174268802129988320467485630854362607420594778603548751141966261652946048159742340561321418878325323461280415496684143870222095726555094800851561934920062077098581053064990873075831889262988863577170685702579901106375917685677127517510854434890252202227632819968882204042209977813155911576322438758839117212133144333475303097541505442870752001891207543717729750807403665780805733139589665408714948547479539969655074797355758413252492746181318963662443777174625555745740037680904238852648585446602157569130784611688080213458299144434782404446632396161494418397414110967220792361627037416963153902049518286576715684058577311870707764077237853902275414358317406584908405498875498704521847342686987573468465859123104573049282333991622834006883804181647516979504674177737103915501496410989112741585083898404719924012433286485556850302897686943639747616443405525997134629249102537302657589689748022067944661365787721410006802753424376253390690455051473511879267686728828040116448789454747991065214975115575618426973514831568007856523214931624053552838679936898072783240150682474408187416275461894645002976300078086846458558958446188233823917017268608126008560374725220271404739531005223228332813444928383618449214304342883329283192522418704865383833918134376657505265608747452128868092817414539130966289955836356699499614565745185823379832016150543419173615945213335586469665533406455394250783877874864459640817970946803811400031942419585406791386620725555528215724935989708661385150080918985335902393064429432671267171655676116126677422777154847606284017929435735485957877715173376"
Y 是
"6050060671375366504479199680125555354571111154849793880846497346573918278439742113929535410412245001"
预期输出是
2714709153644434292890637136888628957228400268048279162148640553691601004498358288050293961305023875148228273010824422271138903421134733326499044301847851158101848246729046992292909107333444875858017958025203597855055812830986687143052631072076649809056039978122257185656034679528706672846688011536999078089749888678505315971952805072341192056527382788217887418441960382555841614670478228163281677761159417547548554993786592112004501447929755606530404731638799261993116079176299334696481924788634012248288502540328313616013165637320197713118675923899969461180288468550560535099983756260244369896665420990179629898732529665632523546525359883919625736940536257042035390574775059530681917411793233487460031446497457268493630310402289794288468210593375152581738025730273212579346581752210008007711088995071200471248909606299030963613520560331527763906078869065256971415868297652656347226479445032539918934978146316973389307612633359506085000990830697527022193186543224233784549091912007371340295545123367471779533973217465499957522325389970735168749615900461310038733143340874469272137483874894918947851314071067975516772414692577427000418074268390836563034028592944665560388145585108472561417834830343056550158869842789867892951283205318599637205688693751186392554470186022295601201188838042578293880234887854802505071515199429046309269599098886600508634716003172744947894003360097289770901313938320108852484194764220775974932481184202720481525896253015284478662113700091305971042294149676575345050665026564991910889907732476095733839372187514658877115143218505340849650984734829731584436615635605841914987329570724893957162020100083569127335620208593598036108210303683889788488521481074027109888040831533904429548599649450741396493975027952511356433442227794283636988927964009373837222090191465321415588274405013777176974106101478767563894624180901897778292106644360559869302169605249778185968915451466991959084820855332938259956567290576301796233386102937323105206419829161130896230126627709744227818204552832331999487040347791035747832809638334637116619148486300881494277499665632977192468572425238854322142502401261557212067843715468050787934094885241317312473276168439201163382745193921612694138535376704496227953229035057718512597569089476033841199788895923877372266099970306542598120437168891127681001960867994015101157953469132100431547905683909270695201742594193388499848320908562661911425751314810474731727057550449239800848781120949277737382298099496929604849253973414102490047232888258745037182513309284709056190158841222798999721228801879910976211421559678494787414944250436404083973432028138333131476065893686104293376
格式化为包含 3 位单元格的向量,实际输出为
2623705611112669690531476608481329088395435490079090713131177118299324844137849203579365903291836640603666
格式化为包含 3 位单元格的向量。
成功了!
有点。下面的代码可以让我在虚拟机上准确地计算示例和后续示例。回想起来,我的错误是愚蠢而明显的;我没有考虑到每个后续 B 周期的细胞变化。基本上以123*45为例,我不是加615+4920,而是加615+492。除了在我的情况下它是三个数字而不是 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;
现在我提到它适用于虚拟计算器。不幸的是,我在 ACTUAL 计算器上收到 "Invalid Input" 错误。这意味着在某个地方,它错误地计算了矩阵中的某些东西,这些东西非常复杂,以至于不会在虚拟上出错。而且由于Virtual真的只是为了bug测试,所以问题还是没有解决。
更新:程序没有正确保存到计算器。现在工作正常。现在减少每次乘法时执行的超过 200 万次操作。理论上 colDim() 可以做到这一点,但目前的努力尚未证明是成功的。
(与 TI-BASIC 社区共享,因为 HP Prime 社区在 Stack Exchange 上几乎不存在,并且因为双向移植程序并不难,至少以我的经验而言。)
我试图通过创建一个基于矩阵的任意数字库来提高我的计算器能力。到目前为止,我一直在得到准确的答案。
我一直在努力创建一个任意数字库来扩展我的 HP Prime 上的溢出,并增加精度。我通过将两个字符串输入解析为矩阵并在逐个单元格的基础上执行操作(溢出)来完成此操作。到目前为止,它似乎可以毫无问题地执行 +/-/* 操作。在计算期间探测超出计算器默认 1x10^500 限制(目前我的程序理论上上限为 1x10^3000,可以选择将其提高到 1x10^81,000)。为此,我尝试计算 4^4200 * 99^50。我收到的结果小于 1*10^223,我知道这不是正确的值。所以在某个地方它要么错误地乘以单元格,要么截断输入字符串。如果你想看看这个内置计算器,但你没有,惠普在他们的网站上免费提供了一个官方模拟器。 (使用 Delphi 语法突出显示近似 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;
其中 X 是
"448707757012839455309988823384023570217382023410572352132240159311976273559306909949896086662607760278124606679518751885625884533694619507503026349914768426861747593802280773821772416408875901487066526265026305667941615575166174903872068087743676760199083667121277668311584275009665264903864515944617908712723287459232291260129634276229908301402499971955385457162445529951417773148752185812095502631183129165210524830514114465987973781359281956167647888699479090990161019577468495049848196418783654076433180861846461599104044973457213015089019356982008879191317969405874158682767654151166482515723607747513680058428646600294620339178864798770475883170920418838166581453611522008467230703367447366497621385458219132583927289676302395042470581032749514332565175967813899473859769146838779167186771656891644069759727377159974612337367385809154100630846287921465865344914641493458819884053851214622278988653511235185959968366171629847583944618207182864243509174268802129988320467485630854362607420594778603548751141966261652946048159742340561321418878325323461280415496684143870222095726555094800851561934920062077098581053064990873075831889262988863577170685702579901106375917685677127517510854434890252202227632819968882204042209977813155911576322438758839117212133144333475303097541505442870752001891207543717729750807403665780805733139589665408714948547479539969655074797355758413252492746181318963662443777174625555745740037680904238852648585446602157569130784611688080213458299144434782404446632396161494418397414110967220792361627037416963153902049518286576715684058577311870707764077237853902275414358317406584908405498875498704521847342686987573468465859123104573049282333991622834006883804181647516979504674177737103915501496410989112741585083898404719924012433286485556850302897686943639747616443405525997134629249102537302657589689748022067944661365787721410006802753424376253390690455051473511879267686728828040116448789454747991065214975115575618426973514831568007856523214931624053552838679936898072783240150682474408187416275461894645002976300078086846458558958446188233823917017268608126008560374725220271404739531005223228332813444928383618449214304342883329283192522418704865383833918134376657505265608747452128868092817414539130966289955836356699499614565745185823379832016150543419173615945213335586469665533406455394250783877874864459640817970946803811400031942419585406791386620725555528215724935989708661385150080918985335902393064429432671267171655676116126677422777154847606284017929435735485957877715173376"
Y 是
"6050060671375366504479199680125555354571111154849793880846497346573918278439742113929535410412245001"
预期输出是
2714709153644434292890637136888628957228400268048279162148640553691601004498358288050293961305023875148228273010824422271138903421134733326499044301847851158101848246729046992292909107333444875858017958025203597855055812830986687143052631072076649809056039978122257185656034679528706672846688011536999078089749888678505315971952805072341192056527382788217887418441960382555841614670478228163281677761159417547548554993786592112004501447929755606530404731638799261993116079176299334696481924788634012248288502540328313616013165637320197713118675923899969461180288468550560535099983756260244369896665420990179629898732529665632523546525359883919625736940536257042035390574775059530681917411793233487460031446497457268493630310402289794288468210593375152581738025730273212579346581752210008007711088995071200471248909606299030963613520560331527763906078869065256971415868297652656347226479445032539918934978146316973389307612633359506085000990830697527022193186543224233784549091912007371340295545123367471779533973217465499957522325389970735168749615900461310038733143340874469272137483874894918947851314071067975516772414692577427000418074268390836563034028592944665560388145585108472561417834830343056550158869842789867892951283205318599637205688693751186392554470186022295601201188838042578293880234887854802505071515199429046309269599098886600508634716003172744947894003360097289770901313938320108852484194764220775974932481184202720481525896253015284478662113700091305971042294149676575345050665026564991910889907732476095733839372187514658877115143218505340849650984734829731584436615635605841914987329570724893957162020100083569127335620208593598036108210303683889788488521481074027109888040831533904429548599649450741396493975027952511356433442227794283636988927964009373837222090191465321415588274405013777176974106101478767563894624180901897778292106644360559869302169605249778185968915451466991959084820855332938259956567290576301796233386102937323105206419829161130896230126627709744227818204552832331999487040347791035747832809638334637116619148486300881494277499665632977192468572425238854322142502401261557212067843715468050787934094885241317312473276168439201163382745193921612694138535376704496227953229035057718512597569089476033841199788895923877372266099970306542598120437168891127681001960867994015101157953469132100431547905683909270695201742594193388499848320908562661911425751314810474731727057550449239800848781120949277737382298099496929604849253973414102490047232888258745037182513309284709056190158841222798999721228801879910976211421559678494787414944250436404083973432028138333131476065893686104293376
格式化为包含 3 位单元格的向量,实际输出为
2623705611112669690531476608481329088395435490079090713131177118299324844137849203579365903291836640603666
格式化为包含 3 位单元格的向量。
成功了!
有点。下面的代码可以让我在虚拟机上准确地计算示例和后续示例。回想起来,我的错误是愚蠢而明显的;我没有考虑到每个后续 B 周期的细胞变化。基本上以123*45为例,我不是加615+4920,而是加615+492。除了在我的情况下它是三个数字而不是 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;
现在我提到它适用于虚拟计算器。不幸的是,我在 ACTUAL 计算器上收到 "Invalid Input" 错误。这意味着在某个地方,它错误地计算了矩阵中的某些东西,这些东西非常复杂,以至于不会在虚拟上出错。而且由于Virtual真的只是为了bug测试,所以问题还是没有解决。
更新:程序没有正确保存到计算器。现在工作正常。现在减少每次乘法时执行的超过 200 万次操作。理论上 colDim() 可以做到这一点,但目前的努力尚未证明是成功的。