Умножение с использованием библиотеки произвольных чисел на основе матрицы (HP Prime)

(Поделился с сообществом TI-BASIC, потому что сообщество HP Prime почти не существует на Stack Exchange, а также потому, что перенос программ в обоих направлениях не был слишком сложным, по крайней мере, по моему опыту.)

Я пытаюсь расширить возможности своих калькуляторов, создав библиотеку произвольных чисел на основе матрицы. Я получаю точные ответы до сих пор.

Я работал над созданием библиотеки произвольных чисел, чтобы расширить возможности переполнения на моем HP Prime, а также повысить точность. Я сделал это, проанализировав два строковых ввода в матрицы и выполнив операции с ячейкой за ячейкой с переполнением. До сих пор казалось, что операции +/-/* выполняются без проблем. Во время расчета, чтобы исследовать предел калькулятора по умолчанию 1x10 ^ 500 (в настоящее время моя программа теоретически ограничивает 1x10 ^ 3000 с возможностью увеличения до 1x10 ^ 81 000). Для этого я попытался вычислить 4^4200 * 99^50. Результат, который я получил, был меньше 1 * 10 ^ 223, что, как я знал, не могло быть правильным значением. Так что где-то это либо неправильное умножение ячеек, либо усечение входной строки. Если вы хотите посмотреть на этот встроенный калькулятор, но у вас его нет, HP предлагает бесплатный официальный эмулятор со своего веб-сайта. (используя подсветку синтаксиса 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;

Где Х

"448707757012839455309988823384023570217382023410572352132240159311976273559306909949896086662607760278124606679518751885625884533694619507503026349914768426861747593802280773821772416408875901487066526265026305667941615575166174903872068087743676760199083667121277668311584275009665264903864515944617908712723287459232291260129634276229908301402499971955385457162445529951417773148752185812095502631183129165210524830514114465987973781359281956167647888699479090990161019577468495049848196418783654076433180861846461599104044973457213015089019356982008879191317969405874158682767654151166482515723607747513680058428646600294620339178864798770475883170920418838166581453611522008467230703367447366497621385458219132583927289676302395042470581032749514332565175967813899473859769146838779167186771656891644069759727377159974612337367385809154100630846287921465865344914641493458819884053851214622278988653511235185959968366171629847583944618207182864243509174268802129988320467485630854362607420594778603548751141966261652946048159742340561321418878325323461280415496684143870222095726555094800851561934920062077098581053064990873075831889262988863577170685702579901106375917685677127517510854434890252202227632819968882204042209977813155911576322438758839117212133144333475303097541505442870752001891207543717729750807403665780805733139589665408714948547479539969655074797355758413252492746181318963662443777174625555745740037680904238852648585446602157569130784611688080213458299144434782404446632396161494418397414110967220792361627037416963153902049518286576715684058577311870707764077237853902275414358317406584908405498875498704521847342686987573468465859123104573049282333991622834006883804181647516979504674177737103915501496410989112741585083898404719924012433286485556850302897686943639747616443405525997134629249102537302657589689748022067944661365787721410006802753424376253390690455051473511879267686728828040116448789454747991065214975115575618426973514831568007856523214931624053552838679936898072783240150682474408187416275461894645002976300078086846458558958446188233823917017268608126008560374725220271404739531005223228332813444928383618449214304342883329283192522418704865383833918134376657505265608747452128868092817414539130966289955836356699499614565745185823379832016150543419173615945213335586469665533406455394250783877874864459640817970946803811400031942419585406791386620725555528215724935989708661385150080918985335902393064429432671267171655676116126677422777154847606284017929435735485957877715173376"

и Y

"6050060671375366504479199680125555354571111154849793880846497346573918278439742113929535410412245001"

ожидаемый результат

2714709153644434292890637136888628957228400268048279162148640553691601004498358288050293961305023875148228273010824422271138903421134733326499044301847851158101848246729046992292909107333444875858017958025203597855055812830986687143052631072076649809056039978122257185656034679528706672846688011536999078089749888678505315971952805072341192056527382788217887418441960382555841614670478228163281677761159417547548554993786592112004501447929755606530404731638799261993116079176299334696481924788634012248288502540328313616013165637320197713118675923899969461180288468550560535099983756260244369896665420990179629898732529665632523546525359883919625736940536257042035390574775059530681917411793233487460031446497457268493630310402289794288468210593375152581738025730273212579346581752210008007711088995071200471248909606299030963613520560331527763906078869065256971415868297652656347226479445032539918934978146316973389307612633359506085000990830697527022193186543224233784549091912007371340295545123367471779533973217465499957522325389970735168749615900461310038733143340874469272137483874894918947851314071067975516772414692577427000418074268390836563034028592944665560388145585108472561417834830343056550158869842789867892951283205318599637205688693751186392554470186022295601201188838042578293880234887854802505071515199429046309269599098886600508634716003172744947894003360097289770901313938320108852484194764220775974932481184202720481525896253015284478662113700091305971042294149676575345050665026564991910889907732476095733839372187514658877115143218505340849650984734829731584436615635605841914987329570724893957162020100083569127335620208593598036108210303683889788488521481074027109888040831533904429548599649450741396493975027952511356433442227794283636988927964009373837222090191465321415588274405013777176974106101478767563894624180901897778292106644360559869302169605249778185968915451466991959084820855332938259956567290576301796233386102937323105206419829161130896230126627709744227818204552832331999487040347791035747832809638334637116619148486300881494277499665632977192468572425238854322142502401261557212067843715468050787934094885241317312473276168439201163382745193921612694138535376704496227953229035057718512597569089476033841199788895923877372266099970306542598120437168891127681001960867994015101157953469132100431547905683909270695201742594193388499848320908562661911425751314810474731727057550449239800848781120949277737382298099496929604849253973414102490047232888258745037182513309284709056190158841222798999721228801879910976211421559678494787414944250436404083973432028138333131476065893686104293376

отформатирован как вектор с 3-значными ячейками, фактический результат

2623705611112669690531476608481329088395435490079090713131177118299324844137849203579365903291836640603666

отформатирован как вектор с 3-значными ячейками.


person IdriveaTARDIS    schedule 05.09.2019    source источник


Ответы (1)


ОНО РАБОТАЕТ!

Вроде. Следующий код позволяет мне точно рассчитать пример и последующие примеры на виртуальной машине. Моя ошибка была глупой и очевидной в ретроспективе; Мне не удалось учесть сдвиг клеток от каждого последующего В-цикла. В общем, возьмем, например, 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;

Теперь я упомянул, что это работало на виртуальном калькуляторе. К сожалению, я получаю сообщение об ошибке «Неверный ввод» на АКТУАЛЬНОМ калькуляторе. Это означает, что где-то он неправильно вычисляет что-то в матрицах, которые достаточно сложны, чтобы не ошибиться на виртуальном. А так как виртуалка действительно только для багтестинга, то проблема так и осталась нерешенной.

ОБНОВЛЕНИЕ: Программа не сохранялась в калькулятор правильно. Теперь работает нормально. Теперь, чтобы сократить более двух миллионов операций, выполняемых каждый раз, когда вы хотите умножить. Теоретически colDim() может это сделать, но текущие попытки не увенчались успехом.

person IdriveaTARDIS    schedule 10.09.2019