From ac57431ac4432efa05a6b38ba6430da71b0d6638 Mon Sep 17 00:00:00 2001 From: nils polek Date: Mon, 15 Jan 2024 16:28:41 +0000 Subject: [PATCH] added big int lib --- Makefile | 4 +- bigint/Makefile | 22 + bigint/README | 92 +++ bigint/build/bin/testbip | Bin 0 -> 60832 bytes bigint/build/include/bigint.h | 60 ++ bigint/build/include/support.h | 15 + bigint/build/lib/libbigint.a | Bin 0 -> 28626 bytes bigint/src/Makefile | 26 + bigint/src/bigint.c | 987 +++++++++++++++++++++++++ bigint/src/bigint.h | 60 ++ bigint/src/bigint.o | Bin 0 -> 28344 bytes bigint/src/libbigint.a | Bin 0 -> 28626 bytes bigint/src/support.h | 15 + bigint/tst/Makefile | 28 + bigint/tst/support.c | 55 ++ bigint/tst/support.o | Bin 0 -> 4832 bytes bigint/tst/testbip | Bin 0 -> 60832 bytes bigint/tst/testbip.c | 1253 ++++++++++++++++++++++++++++++++ bigint/tst/testbip.o | Bin 0 -> 62728 bytes 19 files changed, 2615 insertions(+), 2 deletions(-) create mode 100644 bigint/Makefile create mode 100644 bigint/README create mode 100755 bigint/build/bin/testbip create mode 100644 bigint/build/include/bigint.h create mode 100644 bigint/build/include/support.h create mode 100644 bigint/build/lib/libbigint.a create mode 100644 bigint/src/Makefile create mode 100644 bigint/src/bigint.c create mode 100644 bigint/src/bigint.h create mode 100644 bigint/src/bigint.o create mode 100644 bigint/src/libbigint.a create mode 100644 bigint/src/support.h create mode 100644 bigint/tst/Makefile create mode 100644 bigint/tst/support.c create mode 100644 bigint/tst/support.o create mode 100755 bigint/tst/testbip create mode 100644 bigint/tst/testbip.c create mode 100644 bigint/tst/testbip.o diff --git a/Makefile b/Makefile index 1d0990c..96df21d 100644 --- a/Makefile +++ b/Makefile @@ -7,10 +7,10 @@ CC = gcc F = prog.bin # Compiler flags -CFLAGS = -g -Wall -std=c99 -pedantic +CFLAGS = -I ./bigint/build/include -L ./bigint/build/lib -g -Wall -std=c99 -pedantic # Source file -SRC = njvm.c +SRC = njvm.c # Executable name TARGET = njvm diff --git a/bigint/Makefile b/bigint/Makefile new file mode 100644 index 0000000..5b9ac79 --- /dev/null +++ b/bigint/Makefile @@ -0,0 +1,22 @@ +# +# Makefile for big integer library and test +# + +DIRS = src tst + +all: + for i in $(DIRS) ; do \ + $(MAKE) -C $$i install ; \ + done + +clean: + for i in $(DIRS) ; do \ + $(MAKE) -C $$i clean ; \ + done + rm -rf ./build + rm -f *~ + +dist: clean + (cd .. ; \ + tar -cvf bigint.tar bigint ; \ + gzip -f bigint.tar) diff --git a/bigint/README b/bigint/README new file mode 100644 index 0000000..0f0534d --- /dev/null +++ b/bigint/README @@ -0,0 +1,92 @@ +The "bigint" Package +==================== + +1. What is it? +-------------- + +This package implements a multiple-precision integer arithmetic package, +i.e., a collection of functions which can calculate with integers having +arbitrarily many digits. The algorithms are taken from [D. Knuth: The +Art of Computer Programming, Vol. 2, Seminumerical Algorithms], the +implementation language is C. + + +2. "Multiple Precision" - how does it work? +------------------------------------------- + +Each integer number is represented as an array of digits. The array +is large enough to hold the number of digits necessary to represent +the number. Each digit occupies a single byte, so the number base of +this representation is 256. Addition, subtraction, and multiplication +work as we all have learned it: perform the desired operation digit +by digit, starting from the least significant digit, and observing +any "carries" from one place to the next higher one. Division is a +little bit more complicated because there is a certain amount of +guesswork involved. Knuth gives a formal treatment of this guesswork. + + +3. How do I use it? +------------------- + +Because every big integer may have a differently sized array to hold +its digits, these structures are dynamically allocated on the heap of +the C runtime system, and accessed by pointers. If you want to perform +an arithmetic operation on one or two big integers, you have to load +the corresponding pointers into a structure called BIP ("Big Integer +Processor"), and call the arithmetic function. When the function has +returned, the pointer to the result of the operation can be found in +another component of the BIP. The following functions are available: + + int bigSgn(void); /* sign */ + int bigCmp(void); /* comparison */ + void bigNeg(void); /* negation */ + void bigAdd(void); /* addition */ + void bigSub(void); /* subtraction */ + void bigMul(void); /* multiplication */ + void bigDiv(void); /* division */ + void bigFromInt(int n); /* conversion int --> big */ + int bigToInt(void); /* conversion big --> int */ + void bigRead(FILE *in); /* read a big integer */ + void bigPrint(FILE *out); /* print a big integer */ + void bigDump(FILE *out, BigObjRef bigObjRef); /* dump a big integer */ + +Some of these functions accept or return ordinary integers. For the +exact definition of each function's interface, please see the comments +in the function's source. + + +4. What else is needed? +----------------------- + +The library tries to detect fatal errors in using its functions (e.g., +null pointers to operands) as well as internal errors (which "cannot +happen"). In either case a user-supplied error routine is called, which +is supposed to print an error message and then to terminate the program. + +The library does not attempt to manage memory. For this purpose, it +relies on a user-supplied function "void* newPrimObject(int dataSize)", +which should allocate sufficiently many bytes and return a pointer to +a created object. In addition, the library needs to access a data field +- that implements the size-as-needed cocept - within the created object, +to actualy manage the data structures that represent the values of the +integer number. For this, the following function can be used: + +void * getPrimObjectDataPointer(void * obj){ + ObjRef oo = ((ObjRef) (obj)); + return oo->data; +} + +This function must also be a user-supplied function that must be +implemented by the program that wants to use this library. + +For details about these three user-supplied functions take a look in +the file "support.c" in the directory "tst". + + +5. What is in the directory "tst"? +---------------------------------- + +Well, you may have guessed it already: these are test cases for the +library. You can learn how to link against the library by inspecting +the "Makefile" for the tests, and you can find a simple implementation +of the support library. diff --git a/bigint/build/bin/testbip b/bigint/build/bin/testbip new file mode 100755 index 0000000000000000000000000000000000000000..6d9fe44d411bc478834bf1b1d7e6dbe40cf7d3f4 GIT binary patch literal 60832 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 literal 0 HcmV?d00001 diff --git a/bigint/build/include/bigint.h b/bigint/build/include/bigint.h new file mode 100644 index 0000000..b93d88e --- /dev/null +++ b/bigint/build/include/bigint.h @@ -0,0 +1,60 @@ +/* + * bigint.h -- big integer library + */ + + +#ifndef _BIGINT_H_ +#define _BIGINT_H_ + + +/* object representation */ +typedef void* BigObjRef; + + +#include + + +typedef struct { + int nd; /* number of digits; array may be bigger */ + /* nd = 0 exactly when number = 0 */ + unsigned char sign; /* one of BIG_NEGATIVE or BIG_POSITIVE */ + /* zero always has BIG_POSITIVE here */ + unsigned char digits[1]; /* the digits proper; number base is 256 */ + /* LS digit first; MS digit is not zero */ +} Big; + +#include "support.h" + + +/* big integer processor registers */ + +typedef struct { + BigObjRef op1; /* first (or single) operand */ + BigObjRef op2; /* second operand (if present) */ + BigObjRef res; /* result of operation */ + BigObjRef rem; /* remainder in case of division */ +} BIP; + +extern BIP bip; /* registers of the processor */ + + +/* big integer processor functions */ + +int bigSgn(void); /* sign */ +int bigCmp(void); /* comparison */ +void bigNeg(void); /* negation */ +void bigAdd(void); /* addition */ +void bigSub(void); /* subtraction */ +void bigMul(void); /* multiplication */ +void bigDiv(void); /* division */ + +void bigFromInt(int n); /* conversion int --> big */ +int bigToInt(void); /* conversion big --> int */ + +void bigRead(FILE *in); /* read a big integer */ +void bigPrint(FILE *out); /* print a big integer */ + +void bigDump(FILE *out, BigObjRef bigObjRef); /* dump a big integer object */ + + +#endif /* _BIGINT_H_ */ diff --git a/bigint/build/include/support.h b/bigint/build/include/support.h new file mode 100644 index 0000000..8e4455e --- /dev/null +++ b/bigint/build/include/support.h @@ -0,0 +1,15 @@ +/* + * support.h -- object representation and support functions + */ + + +#ifndef _SUPPORT_H_ +#define _SUPPORT_H_ + +/* support functions */ + +void fatalError(char *msg); /* print a message and exit */ +void * newPrimObject(int dataSize); /* create a new primitive object */ +void * getPrimObjectDataPointer(void * primObject); + +#endif /* _SUPPORT_H_ */ diff --git a/bigint/build/lib/libbigint.a b/bigint/build/lib/libbigint.a new file mode 100644 index 0000000000000000000000000000000000000000..a4ddb1ac5774479937ecf705b14d491451c1e572 GIT binary patch literal 28626 zcmc(H30zIh|NpryO46-}5YM$li_(V3UYG1?vGhn* zW@(Pj=Bum{P8l!9>)nZd_WY4u}WP=BD3dZav{WTgzOI#yU|C9Dn?NI(B>Y62OF5b6!cu|g^6 zSFW%Qn!Q#DoWNE9BO;Rr%$NY^$Tqn`+Nia|3Hi2?TLcp8B&EANrIR9a8Z$**F+wQi zfyRIqVd=HKWY)+5Hlmt&m0@M#Twysy;f9yWti)+qMhDvLnHxIG^HYT7yh5==SV4&4 zr#Mweidqx}#0qhiR2fjqS<0+!Tdka34Vg?RjgRn^@*={eREX?e(h5gr2DOa^X~a#Q zM4fTJbmFh3rg+;{-j)@TQbH{lreG`pJJ*HtZ8xAeM6 zrSOz-X*F;ui2gd6E`>DYQpA(eF0JGNmog2nAhrL`1`BXiCGe?Y69t_0l8^=b`Vu+_ zYYWIPkzXq#gjgefTxe5MlQ<&0k{2Y)UczeN&uZY$YFYkdi~?dzra!A`e-ciVHDqNw z(FqLEI$j}gnbuF1%fN^LE^8ZGSg(544GEv9A< zzzMs>IzdUC!>Y2SFq40-Z4ft`gntDMyApcXl@ZMV_mmOtDMRilf$oU_!%ZXN#F8|6Hu<&OB{jP%LYW}w*&xKK;w z|A7h#M1B4hr<52w#hOn*HKGVOJK`OWHK;cP@KWJL*zRw?L9C?#+cK8|@n4(G3xXG1 zj9??Xw2{b|lv#Sk{By!I$xRR?sq{Q>hhT$w;0_$f*!F;U2h9Vi5yECaB($xT%C1Hf z12@re3NLkXrH{Y-|5Lp(ECI|1sZ^WQrH#gw5_Mo~L*~*;2rk*+e9@g&9gJ_{YLxUE za8=t-1)h~-c@}Uo;ZPA4;(6y$O%Hh)5mDH>(#K~P<50t*{J^6=!A4k*`ZI{@e!m?vQdgbVlxGbKg*bD(lC_|QN) z|J+Ue9LeXbm&%|xr+wkDtW|k1PMg5&Pza1F5tg8Ut%+6LSxZiBXwBsx9ZBg(YoUKvHxuj}R_h@K;k)?LejtE)v~zt&(&E;C?HSaUV~2 z?<>5YC8kp5j;Rhbdgf#EI)QIG|F?I$;MRz2wLPGHagAaL5jd%s{UqA+KS0sprn4Fu$H`=M@mhQuAm!O)lWJB%AjP*;7JXj3^QpJ@OE2OsakDmDImxwX%q8A zbUuc6$F2MR&*qvcz4IPf#8IX)yqXkfkx;;rn#p8P(z&3pCLYrI$W)uhWv=ehPoOHH zFmM)CE0mhidI3ZJt^-Y{$abo<3KRl!?UGqcu{Ok%aVu>?ED_wEN_E;gihpIc04v4!``C3&I|<@DoyV| zznHrsIB$e%e{-oL6rdwPhN8S&VIvSh)%GVU#Dd8QEQ5_`8O#c=Q;rZef}5enhz9wk z#bEhs1j}EetXpYV2j4TcU9cMI1uGtH#YWUM&w%u_>e?*}1|7*fFRuys@sYHOdk-GzSQZ!dRzztStWuxEO9|UkJ8}BYf*Y-|DH* zdxR>`jggtb^50wWiq%9Bpfy+5?F_x)I z2`Cu$_anj^jDoe1M~LdRIsk`jDu~E3d$(f z1~x;$ZlQD1!R+aVhJZ;Tq$bF+&6Z=>jy2G)tt|9E>dcQ?L0=)j4IHp9{{%^fQP*aQ z_)q7J=I}$lV|qx3U^%?K#eGHlr62?wfZ?g&E=(tKGEA`fYC?cl2tJAv4NNw|WYCcf zok2`CNV2kO{@~>mHGpkB_}c{2J~M_nT?5@uTdlTh>l)JIwM|VCz6~I1fsU_Q7q-r! zD3Z=;yS&gg>_(ecj5TlWX01cB9Bh+_23eQVs3*-=g>cVfgPjQyD0xbEpgG3b{cdi6 z1{o{FgGDJu_^ox(>hN#iR%RFo4#JI+;7VJ1D@jq>1>P=$n|{02C~3a z>s3P-@QPQVqu`_mBXz@IkfA_*`hpj!P0uN{!`OnD0gbjv3z@3$7dlY&eyiFM!UiyZ zHdqN8!!l@^BqzfK@MzIsLWFg=68K?F6zJ#XBk=Kd4|EF*6^H@@{R0JkO$9~*N85=G z0tegaPE%|I(}XjH_5$0nc6P#Py@4>UdS?G+J@bF8=jpxFdx^KdpTIp-uv`@A&)vSo zKg!{*H~7D-H{^e)2Y%fYKwEi<0-H_jDGCyK1c^Ka-abAeFJOB=Zy!ORNGu8z`FV&K zPqFI-`TGlCUJM-L;qSLp6iC}5$RA3k{QL!;-d^58OF$0%1q25{30(de`j7hlsp~1w z^`Hd0CT6o4J>b*;(>6G*gM{-Tdwq92^LKRW9Q}0E&fVtw)NT|``}1J2mC^RQ+X61E z-qCKcwzt(8t;qw6cNpxeICJLZLv=0P5w^$F9X9mK$+mr@?H?pK)W?vK9lB;{#EZOVhP+9_5Clq%PLrVdQCaJ<>~!M%=iMsI3YJ8zC* z_op2+uc{?Xda%9U+1qo=rlzapZJYeYG(Y0q3!l*tg$?>+__Tk*6A^Q8vE}_mg{-j@!Ar(eToB$ z(sT=7_q2ZNyXM2%l|jbJdt>%aFdy`nd#Ryxpi2F$_{srt1HM~6RhXx8yJ&7#%k3#W z?{!?m8}*DYXI-H)eCX?q<@0YJa};j0IA^%cz^y#7rq4Cw;ZBPUm&GRc2%lrVAkFly zYskDobNTn3EN1KpkZwuZ8E{-}cyz#!OV+Ja#bg6wcD9}X0Y`MZ)J;W zhdpJAI*;bHsvkX(MLNua>w|}0jS3e*suf4r~;{HB~XUmi<-`fof ztywv*`_lT8?aofIw3}%DsK{=tb>zuTNmo;M-yQJHJGbkau%?%VYYD;2{7xdWfx@~6Sfvz)m zr%Vplnv`Jr=VR4@yAGdTTxvV1jJI`Z{^6;1Wsmyh)R#W?*0z{9?19~o2VE+HGneKH zel~hex)4(;byT{i7IuBWU{%9~amRXvmX_7s-7{iYjpJ5rgY8Ft?K*0_V!fR6>pkJ$ z?u}9#aXzRr>GB%gP9=#?6e@lmpbq#xQuu9lqQBhdjUF>iR-`WO7=C{9j**LAcaio? z-W_rMsluj&`F#_He_vN4*<;r!K}|GnR>bgn^^t?EOgru~xai)!Z#$Peql-{qV%y!(nz^&{n$iuKQo-~74Xqjj$HH?3FJnfXdNN^Y^wmA9RTChYq@;+{+KsfMA? z?}zC&roCC@J=k(tmyL^l&wDv&!S6n2=4~2#Am^OMpXy0#pFUjZ7c^jRVU>T3N1o{B z3(XXPzvge_GvXJ!#+~hwzIol5xyP4lO|9N`Bd5Indc%Nyqf3@wHcGrZM$tFVNY5w# z%xsS^GcfZK(I}vU&EP{ce4j+k^$?em^?rk_6i@vy zct2zI7ykj?o3c)>8g`@6HQ(CR;QpP1+dCa!osUCmf>laV-2EEmLq4LI{{HsHM zU;ETo4x5zI&MAKAvF5sS>%|up4?KU+FkfzG@O#Up!aq9f8TQk0cl`+lTsI&rt(+9s;^Ghq&EUK;>*t6^fzb2An>+%!=yx0Ab_^jbsFV8MpZ zpPe#HlH}x9F8Q%jXI0wOOT87p7f$qA_VMf2X{XgA7a0xtyfx6N2k)}-*tDY^P5&A@ zrm|mkzb|UG(O2cFJKI>PxF5V=5!|W0h3+nuS>?x^p9JP*)wee%_p?VW z7GAqxyZq3L#_qrR-^}Yk`10qJT|1Bc6lN000scsu+@nQEi>hu+&K)hEC9 z$$$K0xQqCvsHo_Z`m7}hOaJmakf>=RlzZ;J+``hPm}jW@R>Q3G@=c3EukHIZLpk66 z50Bzb$+Ks~Z**vP-MTVo@9o2>M*f;|C(M>4tf^a9T77?zPGRtczGmY687V2o{EO2= zrt%HLcB=GRxNua#o&15$Hq;x@Ma_ZsMrsEKZhQRP$UNlEgcX;bjaoCO$x(OXpCfm6 z{&j5LNyo8`vtND*>lmMZr;DYhj;t;@7`BBu&zl?qMX&O_qy!5Os9Qw;(GU+Hpo;{Q*2k%!8|!9 zw%txeKWmGehsMiaPe>}d>RFoEw-*ialzHqYIzBs>05GQ<=J?pt^56Ol8fvol*4gp7Q%f4vBE!6Rx_4dH-SVGrU-oTN@r0RsEAsM1 z9=8mhKj@QIYtS>vW}@1pZK2)V?q9ojF|wcH)-BO{t{CP|@8+D=|9M@|gr}*JvvEVF zDJe(wAHA+#q~LUT!+B+$L4xo7T zPph`Q-mtO4eD^ugh9}FFE7ryZuiqi*hRC>@Uu{?W6H~qUBp>?OrdvomBVFIAM`=epxPv9a^<2y3%mYi(LIlr*_pCjaJfIA-}Nq(bWDm$s;GZP17$=>^!YoRQgQm z+z;oAuJdLb8`x#)KHck%>sI~xEnm0&?vASY8P0bTCYj%PSDSGBjhboTQ2D)UZ>-z* zv9NvJPupbAUh_2ej$2n8m|lA`Ii_pXqw5P44?Pw+*qRSIl~F&=XM41l=kA)#V};Lm zRW2Oo?#FXa+!RwSr+HGXDJ^au!=_gH{uj5ZdEIMqWJbtH_ zeX+UM#fUXMqf4H@37>N-^^sD9hUTrIiI;5J9|^c^`*u`t{$_o@vP+lO?EGbuZ54Jl z_u-1i1Frw!T{L9J!6Bcc+6T{zaNyND-kI(_ZIh+dgwD|~j#cf_tQ2-MnGzPtSKfv1J-OIGK(l`EUS3Un0xz0jv2Gp^(Pgm6=(kLq<1 znnoS#URaku$okoLxKU9<&F_JRW|yx;S`AFN?7HT<-!!KuLl5iwbUdNe{Y%#I+ouKl z97ej1@~)g1EnfU5SiS!$xjxlMviQyIr6n^K7wDy(m{4&~yOYK5Uxgoy9Bpk}#hcgc zw_00ec6{!!alT#|S)SUzJe22+d1n;5?PUHjozQol0kirGMLV4%K7KG?bFe1Tr=b4J zg6uv$96TMbRV_PltNs1R_{RC?Q{sw7XRhL#!Qj{*{K`(fth(Co>!INPOb|99S{fDkS;sJ~ zi$=-Lw=Q2Sf6l(==l^DC^1@O3UQGLVEO}w^F`ueL#SUX9H)@St%Fq3I+jH@(sm@1( z9;(+Eq^|Vs6x=muncNpk#X!BGlTwB!9)7a+q@CCN87dJf-F-8!ozggeGIM>$BhlT= z?_b$|G-rc`Z(2Adf(o@Yd^TYa}_+? zYU}CCFCk~iu>Yt5!+kL-PV%Ewi6JIlv;EGm?EmRnvOt!v?xmaDAdaG+!O zfkdN@OFou*JwLQ)Zr{D-2a`H{jM0DSGkHP>C7T`Hzr5-DapAAviTlzwgbz(r?tX7V zmv3cFk(Fmnx6SAq5Zgi0^W5eGaV}wt6!*%B!fX!>3E1xtK4Znvl{Wk%MsLk-gvPB= zFw-9wl2m1zur~45;<>{|bX!K<^muUldH%%GD_iETxxMIgXSs3&fFrI|M9M>dk4X~rWqS~s_hG7&i9I5Y-zHoApV}= z!y(ogZ>=ii=UB`+IV(dFIN-LcQt_=*{u!M<4jOGe#r|ZE1J};DXglQX%K7{Ca)XnJ zj~5x_JBdHK99MgC`{n@sOS2DB6RfR=3-l&TbJ7=>nj4!Ln+nWK%*;(JO-#W!fWtum zK5)wkP{8#LFB1(BfWUFX5y5VT8O~LJMa#ECcBSREWiqujbJt0e}yK z4@|d7&h-{f9z&tBNKQ%%hkgJU@cNJ(?G}zYECXqu68K{4vsH=K2lm?nak@Yv=FDLF z1j`*!`Al}X97BNRL8v^kRr#vs{%%9%wd`_ex2l#l=%0*1`5?%}I>;N)9f56>AQ`gC z1)#hEmBZgOo9n|i;+ZxeM~Assraq9I>J~l5AP)T;7uG}WCQX2P%tz()W?*x9dUN?| zRG!wVAB@vr{exJ3tMZ$4KLwyX6P4cu=gs|)%V89R7)OHQ6u?igvWn%KXM>hfxD5ry zQZqo036Rr3IL^~!0btz_?f{N3(PID{dxH;@L+`tSb2{$95hi(h)H3JzTOXW2{u|U! zdJF&zj&+EiLW7%*dw>l?xDR-s4kkL*!Eqe;K>kJ;*C5gH4UUt*2jYf&h*IFqgO(&u zAt5ageI`%A8K7;Fr#iF+0U}So;L)~7otJaAM;=j?+I2Ohq5upbSAc9@rr#9#y612#*)dL#~jZz72)syl5xW?hFN0v_U^(;$Sy zX#s{B#)lI)njWaJ1djPr2pscW2^{mi5Ds}TG%>z};A1%}IQVe9!9?nRfPv{5fGz(L z!Z9DqPvhV#fH;E*^Rb?)2q*Q|CiqysfP=q);HxstQ6U75<*eqAv!38%Ia@gRcwFOt zVSY9T{}Uk}+u=J0UkwTdiIm?3;iTOxIrw8Z`2HOHWgPrN9Q>0U{7eph9tZz3!N>Ob z!NG5b_Gw`;9Cz5iY6vIo(}%@}OD~phz~aNH9OG6jK9rCBJDI?7yACWl?D674@Ua{b z2Y(X>e6S+Uj$TgP+17{{sjAD+k{kUDD$IVtuR-PTF|}2Y(I+ zKb+u0AHx*I!9U32!?^XK*%Wo0#b?LuQx+e_Etda+#b?Kr8Wai=*)Mwz+?NAijc{x? z-0mI%$MJKBL(W-(kK^YG2S1O+ho^_=-cVE_i_f;t2Ns__uD@{LzgTkEcI%98amfDm zBXHc`fe0t|U%F@a-# zIR{>iaMEs6d&beE{gpUyKEg>kIvo6d9Q>gKAKPa%2Y(5{$NiNMIQGkC4ml|VAIr($ z;D6xYf92qJM9IOGHpd@N@<2md^a4~OO@G~QELeD-*! zpQ-~K+%GIYm&J#+#P)yBlHY26;NWYZEe%qBH-wXRn@I4nA7^mz7jp0eIrtkn_&YfG zBauO{{#YL&!b$y|2|l)`I|qLw!N>A#V8#wrQONrFqo_Vd2M)dpx{$#B z!u{<+;J9A{2^{k+5Kj7cG{MJmCUEd)5`1i*c^v#j9Q-95{M8)%7!Lkcf{*)~z`;LB z@KKh!$idIx;OBDiA93)@Irs|jqD{v9*_i{^K{)A0eGa}U2Vcm+pUS~s$-!U8!Qacl zKg_{TC-~Tp4><6r9CAK#@V{~J+o9i$;rN305%?JtHH1Su!>U*xLlz%Su^2aJ@u90R z?##h==iskr;R2SN1P(ljh4*Ih%UC#DP6G!H{`n%EV1L2niew6KXn#oY@2)%W)-e+^(3wv3y?w$Maq&fn)ir2^`DcfN)r! z-QR5lAInJ~aNO=`mK*`gZkJd%+b?ffcpnzOo{*2*ZDjG;@!1|d*MQd-%-29T)Q`>Y z#li2-!5>TTvEA%BaAyuVOIdh7R)5!W$XU7`AI6pr^^G_s;&z^r`S$y_9vz5hX%Rj}!*?L|jYaxo{REc1pW}o2`2DH zlwVHZC`+v)a3OlmU^juQBRq+~qfoo&30x8Be}ll$bVS`D@G6vlO5oE`yVV35%_ha&u9YoMEDc}-;d6Uta;SaWZV2M@349RB<7c!nKN|532)+WshY_tm_{9YNH{zEPxDfFx z2^_~Ie*PNUSs%%%BlvO1KKQvZ%#TO>-voaO%IlzV%>RJ&!R=riKi72}@nLgli;J#t zfsk_x>4Trk!g8?x-Vl5(l>bKHJ&>NN3XEb{P9x&=B5-@ut{H*fMsmgzxDCRmARJbQ z5Pp6bKd*(`#n0z$BIIDZohI<@Nd84aK7OA0Z-Rde@#WETM7Z5Ws9)_7j`hUPU0V_S z!H7SZz{3zei;#n#>)uW96B)Bp2M9iXKD>zF|Bd87CHVL`^LGS)BkJ#81Rp=IE{~os z!gfeU{PqZk%|Qr1_pU?mqmVv*2tIy(elWowiR9zwvao#o9KIjHZ;#?IgpiM)=Z_`$ zixGc2!N>0f;ODP!fAMwOd4iAMo47^Dzl-{Nm*C^~FWlfoJV;pnLncctCh)#U&&>pm zfA_?%VqiIcBRQ%_VQe@2K1g4LWByEJ=V$^SjPN)@4u0R{6~V`P^3a7SmOl{b(+=TS zA3UE52|kwNPT;GM9lQuR4M_e`f{*3gB=Cz!P7#48BD|cC?||gCoKbFAHq5OCPPeu931fGTRb_AY} z@=gSfugjeYyaMI%dl1+@ZxQZE@IRuwH-Udg`6cK`+FyWh7zQX5Xk-k5*jPas3y8<9VYqR2(F%C!WVF2^`Odvk4r}t04rA=jUAnj^}yy`wp;e zyk3+Oe7x>75;$JJ1jx8pf4mOj>kf?L_0*H#<8?Wb!120&n85LMMK*!s>lw;;NvLm- zn>#oL1v1A4_$*N5<7ONr3JIc&J;57El(GAgC6sZXKa-(LJw@)pUasDLVt>G)&)wYJ z14T;#4OT`_pc{C}2v%*ue7yZcxC&?wpF-G`&U^U#`ij86_cHeL4-y%JSBQ<41i5)E zLU}L0VB>&5{{T^7P$-fsTHq=Ubn_L_;qkxz5&#L%g?Jvr0>_{e@_)4;cVimW1DwH2 zxiQTMb7G4&HVXSPdAPR&>!M|h!uRiR-h()r#=#kr6rf-kiEJOPcTgr-Ux4Zh2pMGF z6qG}mC~TV9xIVrP#|2n_oF4^FXq||HF>rGhq}R|mtVGc0_eW*fPkS~~X}&6Rg!Y3z z!u7HJCIL)V`+9wtdOn1~aDAqfqFiu&44~sST&y6 z|HS~4rGFl3e;c|!W~8;$$9W%cBCGx5sQuMQVc0%=WRq+^9AJ=Qf(yVoO!M`b<8&f0 zFb&%w2GC^HKX1s?Kgk@LzsdT$aQ$WmbK(pG8zdd((EN?t#m7WYg3p^t;AAPP&&J?6 z$-MwDc&STtlL|rgvHxIQn6Um#j-uc?4`q_|kE8mPL;+bp8`PEMKRq$iLIYA5`VZcB zeBTcD>Sfi3F-guHu)c{o{HCa`gu#d`eGMn8zF+}U{~>c|{wC}H EKQ1+h-2eap literal 0 HcmV?d00001 diff --git a/bigint/src/Makefile b/bigint/src/Makefile new file mode 100644 index 0000000..6973380 --- /dev/null +++ b/bigint/src/Makefile @@ -0,0 +1,26 @@ +# +# Makefile for big integer library +# + +BUILD = ../build + +CC = gcc +CFLAGS = -g -Wall + +all: support.h bigint.h libbigint.a + +install: all + mkdir -p $(BUILD)/include + cp support.h $(BUILD)/include + cp bigint.h $(BUILD)/include + mkdir -p $(BUILD)/lib + cp libbigint.a $(BUILD)/lib + +libbigint.a: bigint.o + ar -crs libbigint.a bigint.o + +bigint.o: bigint.c bigint.h support.h + $(CC) $(CFLAGS) -o bigint.o -c bigint.c + +clean: + rm -f *~ bigint.o libbigint.a diff --git a/bigint/src/bigint.c b/bigint/src/bigint.c new file mode 100644 index 0000000..90aa5ab --- /dev/null +++ b/bigint/src/bigint.c @@ -0,0 +1,987 @@ +/* + * bigint.c -- big integer library + */ + + +#include +#include + +#include "bigint.h" + +/**************************************************************/ + +/* debugging */ + + +#define DIV_CHK_01 0 +#define DIV_CHK_02 0 +#define DIV_CHK_03 0 +#define DIV_CHK_04 0 +#define DIV_CHK_05 0 +#define DIV_CHK_06 0 +#define DIV_CHK_07 0 +#define DIV_CHK_08 0 +#define DIV_CHK_09 0 +#define DIV_CHK_10 0 +#define DIV_CHK_11 0 + + +/**************************************************************/ + +/* big integer representation */ + + +#define BIG_NEGATIVE ((unsigned char) 0) +#define BIG_POSITIVE ((unsigned char) 1) + + +#define BIG_PTR(bigObjRef) ((Big *) (getPrimObjectDataPointer(bigObjRef))) +#define GET_ND(bigObjRef) (BIG_PTR(bigObjRef)->nd) +#define SET_ND(bigObjRef, val) (BIG_PTR(bigObjRef)->nd = (val)) +#define GET_SIGN(bigObjRef) (BIG_PTR(bigObjRef)->sign) +#define SET_SIGN(bigObjRef, val) (BIG_PTR(bigObjRef)->sign = (val)) +#define GET_DIGIT(bigObjRef, i) (BIG_PTR(bigObjRef)->digits[i]) +#define SET_DIGIT(bigObjRef, i, val) (BIG_PTR(bigObjRef)->digits[i] = (val)) + + +/**************************************************************/ + +/* global data */ + + +/* + * registers of the big integer processor + */ +BIP bip = { + NULL, /* op1 */ + NULL, /* op2 */ + NULL, /* res */ + NULL, /* rem */ +}; + + +/**************************************************************/ + + +/* + * construct a new big integer object + * + * number of digits is given by parameter + * a reference to a proper object is returned + * but no component of the big integer is set + * + * ATTENTION: All object references stored in + * places other than the bip registers may become + * invalid as soon as this function is called! + */ +static BigObjRef newBig(int nd) { + int dataSize; + BigObjRef bigObjRef; + + dataSize = sizeof(int) + 1 + nd; + bigObjRef = newPrimObject(dataSize); + return bigObjRef; +} + + +/**************************************************************/ + +/* big integer unsigned arithmetic */ + + +/* + * exchange bip.op1 and bip.op2 + */ +static void bigXchg(void) { + BigObjRef tmp; + + tmp = bip.op1; + bip.op1 = bip.op2; + bip.op2 = tmp; +} + + +/* + * big integer unsigned comparison + * + * operands in bip.op1 and bip.op2 + * result is < 0, = 0, or > 0 if and only if the + * same relation holds for bip.op1 and bip.op2 + */ +static int bigUcmp(void) { + int nd1; + int nd2; + int diff; + + /* compare sizes */ + nd1 = GET_ND(bip.op1); + nd2 = GET_ND(bip.op2); + if (nd1 != nd2) { + /* sizes are different: we know the bigger number */ + return nd1 - nd2; + } + /* sizes are equal: we must look at the digits */ + while (nd1--) { + diff = (int) GET_DIGIT(bip.op1, nd1) - + (int) GET_DIGIT(bip.op2, nd1); + if (diff != 0) { + return diff; + } + } + /* the numbers are equal */ + return 0; +} + + +/* + * big integer unsigned addition + * + * operands in bip.op1 and bip.op2 + * result in bip.res + */ +static void bigUadd(void) { + int nd1; + int nd2; + int i; + unsigned short carry; + unsigned short aux; + int xchgFlag; + + /* make sure op1 has at least as many digits as op2 */ + nd1 = GET_ND(bip.op1); + nd2 = GET_ND(bip.op2); + if (nd1 < nd2) { + /* exchange operands */ + bigXchg(); + i = nd1; + nd1 = nd2; + nd2 = i; + xchgFlag = 1; + } else { + /* don't exchange operands */ + xchgFlag = 0; + } + /* allocate result */ + bip.res = newBig(nd1 + 1); + /* copy op2 to result */ + for (i = 0; i < nd2; i++) { + SET_DIGIT(bip.res, i, GET_DIGIT(bip.op2, i)); + } + /* fill result with 0 up to size of op1 */ + for (; i < nd1; i++) { + SET_DIGIT(bip.res, i, 0); + } + /* res = op1 + res */ + carry = 0x00; + for (i = 0; i < nd1; i++) { + aux = (unsigned short) GET_DIGIT(bip.op1, i) + + (unsigned short) GET_DIGIT(bip.res, i) + + carry; + SET_DIGIT(bip.res, i, aux & 0xFF); + carry = aux >> 8; + } + SET_DIGIT(bip.res, i, carry); + /* determine actual size of result */ + i = nd1 + 1; + while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ; + SET_ND(bip.res, i + 1); + /* restore operands */ + if (xchgFlag) { + bigXchg(); + } +} + + +/* + * big integer unsigned subtraction + * + * operands in bip.op1 and bip.op2 + * result in bip.res, must not be negative + */ +static void bigUsub(void) { + int nd1; + int nd2; + int i; + unsigned short carry; + unsigned short aux; + + /* op1 must have at least as many digits as op2 */ + nd1 = GET_ND(bip.op1); + nd2 = GET_ND(bip.op2); + if (nd1 < nd2) { + /* unsigned subtraction would yield negative result */ + fatalError("internal library error #1 - THIS SHOULD NEVER HAPPEN!"); + } + /* allocate result */ + bip.res = newBig(nd1); + /* copy op2 to result */ + for (i = 0; i < nd2; i++) { + SET_DIGIT(bip.res, i, GET_DIGIT(bip.op2, i)); + } + /* fill result with 0 up to size of op1 */ + for (; i < nd1; i++) { + SET_DIGIT(bip.res, i, 0); + } + /* res = op1 - res */ + carry = 0x01; + for (i = 0; i < nd1; i++) { + aux = (unsigned short) GET_DIGIT(bip.op1, i) - + (unsigned short) GET_DIGIT(bip.res, i) + + carry + 0xFF; + SET_DIGIT(bip.res, i, aux & 0xFF); + carry = aux >> 8; + } + if (carry != 0x01) { + /* unsigned subtraction would yield negative result */ + fatalError("internal library error #2 - THIS SHOULD NEVER HAPPEN!"); + } + /* determine actual size of result */ + i = nd1; + while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ; + SET_ND(bip.res, i + 1); +} + + +/* + * big integer unsigned multiplication + * + * operands in bip.op1 and bip.op2 + * result in bip.res + */ +static void bigUmul(void) { + int nd1; + int nd2; + int i, j, k; + unsigned short carry; + unsigned short aux; + + /* get sizes of operands */ + nd1 = GET_ND(bip.op1); + nd2 = GET_ND(bip.op2); + /* allocate result */ + bip.res = newBig(nd1 + nd2); + /* reset lower nd1 digits of result */ + for (i = 0; i < nd1; i++) { + SET_DIGIT(bip.res, i, 0); + } + /* res = op1 * op2 */ + for (j = 0; j < nd2; j++) { + carry = 0x00; + for (k = j, i = 0; i < nd1; k++, i++) { + aux = (unsigned short) GET_DIGIT(bip.op1, i) * + (unsigned short) GET_DIGIT(bip.op2, j) + + (unsigned short) GET_DIGIT(bip.res, k) + + carry; + SET_DIGIT(bip.res, k, aux & 0xFF); + carry = aux >> 8; + } + SET_DIGIT(bip.res, k, carry); + } + /* determine actual size of result */ + i = nd1 + nd2; + while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ; + SET_ND(bip.res, i + 1); +} + + +/* + * big integer unsigned division by single digit divisor + * + * dividend in bip.rem, divisor in parameter + * quotient in bip.rem, remainder is returned + */ +static unsigned char bigUdiv1(unsigned char divisor) { + BigObjRef tmp; + int nd; + int i; + unsigned short d, r; + unsigned short aux; + + /* get size of dividend */ + nd = GET_ND(bip.rem); + /* check for division by zero */ + d = (unsigned short) divisor; + if (d == 0) { + fatalError("internal library error #3 - THIS SHOULD NEVER HAPPEN!"); + } + /* allocate result */ + tmp = newBig(nd); + /* tmp = dividend / divisor, r = dividend % divisor */ + r = 0; + for (i = nd - 1; i >= 0; i--) { + aux = (r << 8) | (unsigned short) GET_DIGIT(bip.rem, i); + SET_DIGIT(tmp, i, aux / d); + r = aux % d; + } + /* determine actual size of quotient */ + i = nd; + while (--i >= 0 && GET_DIGIT(tmp, i) == 0) ; + SET_ND(tmp, i + 1); + /* store quotient */ + bip.rem = tmp; + /* return remainder */ + return (unsigned char) r; +} + + +/* + * big integer unsigned division + * + * dividend in bip.op1, divisor in bip.op2 + * quotient in bip.res, remainder in bip.rem + */ +static void bigUdiv(void) { + BigObjRef tmp; + int nd1; + int nd2; + int nd3; + int i, j, k, l; + unsigned char r; + unsigned short scale; + unsigned short carry; + unsigned short aux; + unsigned short qhat; + unsigned short v1, v2; + unsigned short uj0, uj1, uj2, two; + + /* get sizes of operands */ + nd1 = GET_ND(bip.op1); + nd2 = GET_ND(bip.op2); + /* check for division by zero */ + if (nd2 == 0) { + fatalError("division by zero"); + } + /* check for small dividend */ + if (bigUcmp() < 0) { + /* res = 0 */ + bip.res = newBig(0); + SET_ND(bip.res, 0); + /* rem = op1; BUT THIS HAS TO BE A COPY! */ + bip.rem = newBig(nd1); + for (i = 0; i < nd1; i++) { + SET_DIGIT(bip.rem, i, GET_DIGIT(bip.op1, i)); + } + SET_ND(bip.rem, nd1); + return; + } + /* check for single digit divisor */ + if (nd2 == 1) { + /* yes - use simple division by single digit divisor */ + bip.rem = bip.op1; + r = bigUdiv1(GET_DIGIT(bip.op2, 0)); + bip.res = bip.rem; + if (r == 0) { + bip.rem = newBig(0); + SET_ND(bip.rem, 0); + } else { + bip.rem = newBig(1); + SET_ND(bip.rem, 1); + SET_DIGIT(bip.rem, 0, r); + } + return; + } + /* + * now for the general case + */ +#if DIV_CHK_01 + printf("div_chk #01: division, general case\n"); + printf(" dividend = "); + bigDump(stdout, bip.op1); + printf("\n"); + printf(" divisor = "); + bigDump(stdout, bip.op2); + printf("\n"); +#endif + /* determine scale factor for normalization */ + scale = (unsigned short) 256 / + ((unsigned short) GET_DIGIT(bip.op2, nd2 - 1) + 1); +#if DIV_CHK_02 + printf("div_chk #02: scale factor = %02X\n", scale); +#endif + /* normalize dividend, result is in bip.rem */ + bip.rem = newBig(nd1 + 1); + carry = 0x00; + for (i = 0; i < nd1; i++) { + aux = (unsigned short) GET_DIGIT(bip.op1, i) * scale + + carry; + SET_DIGIT(bip.rem, i, aux & 0xFF); + carry = aux >> 8; + } + SET_DIGIT(bip.rem, i, carry); + SET_ND(bip.rem, nd1 + 1); +#if DIV_CHK_03 + printf("div_chk #03: normalized dividend = "); + bigDump(stdout, bip.rem); + printf("\n"); +#endif + /* normalize divisor, result is in bip.res */ + bip.res = newBig(nd2); + carry = 0x00; + for (i = 0; i < nd2; i++) { + aux = (unsigned short) GET_DIGIT(bip.op2, i) * scale + + carry; + SET_DIGIT(bip.res, i, aux & 0xFF); + carry = aux >> 8; + } + if (carry != 0x00) { + /* overflow in divisor normalization */ + fatalError("internal library error #4 - THIS SHOULD NEVER HAPPEN!"); + } + SET_ND(bip.res, nd2); +#if DIV_CHK_04 + printf("div_chk #04: normalized divisor = "); + bigDump(stdout, bip.res); + printf("\n"); +#endif + /* allocate quotient */ + nd3 = nd1 - nd2 + 1; + tmp = newBig(nd3); + /* extract the two most significand digits of divisor */ + v1 = (unsigned short) GET_DIGIT(bip.res, nd2 - 1); + v2 = (unsigned short) GET_DIGIT(bip.res, nd2 - 2); + /* loop on digits of dividend and compute digits of quotient */ + /* j is index into dividend, k is index into quotient */ + for (j = nd1, k = nd3 - 1; k >= 0; j--, k--) { +#if DIV_CHK_05 + printf("div_chk #05: j = %d, k = %d\n", j, k); +#endif + /* calculate qhat */ + uj0 = (unsigned short) GET_DIGIT(bip.rem, j); + uj1 = (unsigned short) GET_DIGIT(bip.rem, j - 1); + uj2 = (unsigned short) GET_DIGIT(bip.rem, j - 2); + two = (uj0 << 8) | uj1; + if (uj0 == v1) { + qhat = (unsigned short) 255; +#if DIV_CHK_06 + printf("div_chk #06a: qhat = %02X\n", qhat); +#endif + } else { + qhat = two / v1; +#if DIV_CHK_06 + printf("div_chk #06b: qhat = %02X\n", qhat); +#endif + } + while (qhat * v2 > (((two - qhat * v1) << 8) | uj2)) { + qhat--; +#if DIV_CHK_07 + printf("div_chk #07: qhat decremented, is now %02X\n", qhat); +#endif + } + /* multiply and subtract */ + /* l is index into dividend, i is index into divisor */ + carry = 0xFF; + for (l = j - nd2, i = 0; i < nd2; l++, i++) { + aux = (unsigned short) GET_DIGIT(bip.rem, l) - + (unsigned short) GET_DIGIT(bip.res, i) * qhat + + carry + 0xFE01; + SET_DIGIT(bip.rem, l, aux & 0xFF); + carry = aux >> 8; + } + aux = (unsigned short) GET_DIGIT(bip.rem, l) + + carry + 0xFE01; + SET_DIGIT(bip.rem, l, aux & 0xFF); + carry = aux >> 8; +#if DIV_CHK_08 + printf("div_chk #08: remainder = "); + bigDump(stdout, bip.rem); + printf("\n"); +#endif + /* test remainder and possibly add back */ + if (carry != 0xFF) { + /* qhat is one too large */ + qhat--; +#if DIV_CHK_09 + printf("div_chk #09: qhat final correction, is now %02X\n", qhat); +#endif + /* add back */ + /* l is index into dividend, i is index into divisor */ + carry = 0x00; + for (l = j - nd2, i = 0; i < nd2; l++, i++) { + aux = (unsigned short) GET_DIGIT(bip.rem, l) + + (unsigned short) GET_DIGIT(bip.res, i) + + carry; + SET_DIGIT(bip.rem, l, aux & 0xFF); + carry = aux >> 8; + } + aux = (unsigned short) GET_DIGIT(bip.rem, l) + + carry; + SET_DIGIT(bip.rem, l, aux & 0xFF); + carry = aux >> 8; + if (carry != 0x01) { + /* missing carry in add-back sum */ + fatalError("internal library error #5 - THIS SHOULD NEVER HAPPEN!"); + } +#if DIV_CHK_10 + printf("div_chk #10: remainder = "); + bigDump(stdout, bip.rem); + printf("\n"); +#endif + } + /* store quotient digit */ + SET_DIGIT(tmp, k, qhat); +#if DIV_CHK_11 + printf("div_chk #11: quotient digit = %02X\n", qhat); +#endif + } + /* finish quotient */ + i = nd3; + while (--i >= 0 && GET_DIGIT(tmp, i) == 0) ; + SET_ND(tmp, i + 1); + bip.res = tmp; + /* finish and unnormalize remainder */ + i = nd1 + 1; + while (--i >= 0 && GET_DIGIT(bip.rem, i) == 0) ; + SET_ND(bip.rem, i + 1); + r = bigUdiv1(scale); + if (r != 0) { + /* non-zero remainder in unnormalization */ + fatalError("internal library error #6 - THIS SHOULD NEVER HAPPEN!"); + } +} + + +/**************************************************************/ + +/* nil reference exception */ + + +static void nilRefException(void) { + fatalError("big integer library detected illegal nil reference"); +} + + +/**************************************************************/ + +/* big integer arithmetic */ + + +/* + * big integer sign + * + * operand in bip.op1 + * result is < 0, = 0, or > 0 if and only if + * the same relation holds for bip.op1 + */ +int bigSgn(void) { + if (bip.op1 == NULL) { + nilRefException(); + } + if (GET_ND(bip.op1) == 0) { + return 0; + } + if (GET_SIGN(bip.op1) == BIG_POSITIVE) { + return 1; + } else { + return -1; + } +} + + +/* + * big integer comparison + * + * operands in bip.op1 and bip.op2 + * result is < 0, = 0, or > 0 if and only if the + * same relation holds for bip.op1 and bip.op2 + */ +int bigCmp(void) { + if (bip.op1 == NULL || + bip.op2 == NULL) { + nilRefException(); + } + if (GET_SIGN(bip.op1) == BIG_POSITIVE) { + if (GET_SIGN(bip.op2) == BIG_POSITIVE) { + /* op1 >= 0 and op2 >= 0 */ + return bigUcmp(); + } else { + /* op1 >= 0 and op2 < 0 */ + return 1; + } + } else { + if (GET_SIGN(bip.op2) == BIG_POSITIVE) { + /* op1 < 0 and op2 >= 0 */ + return -1; + } else { + /* op1 < 0 and op2 < 0 */ + return -bigUcmp(); + } + } +} + + +/* + * big integer negation + * + * operand in bip.op1 + * result in bip.res + */ +void bigNeg(void) { + int nd; + int i; + + if (bip.op1 == NULL) { + nilRefException(); + } + /* make copy of operand */ + nd = GET_ND(bip.op1); + bip.res = newBig(nd); + for (i = 0; i < nd; i++) { + SET_DIGIT(bip.res, i, GET_DIGIT(bip.op1, i)); + } + SET_ND(bip.res, nd); + /* store inverted sign */ + if (GET_SIGN(bip.op1) == BIG_NEGATIVE || nd == 0) { + SET_SIGN(bip.res, BIG_POSITIVE); + } else { + SET_SIGN(bip.res, BIG_NEGATIVE); + } +} + + +/* + * big integer addition + * + * operands in bip.op1 and bip.op2 + * result in bip.res + */ +void bigAdd(void) { + if (bip.op1 == NULL || + bip.op2 == NULL) { + nilRefException(); + } + if (GET_SIGN(bip.op1) == BIG_POSITIVE) { + if (GET_SIGN(bip.op2) == BIG_POSITIVE) { + /* op1 >= 0 and op2 >= 0 */ + bigUadd(); + SET_SIGN(bip.res, BIG_POSITIVE); + } else { + /* op1 >= 0 and op2 < 0 */ + if (bigUcmp() >= 0) { + /* |op1| >= |op2| */ + bigUsub(); + SET_SIGN(bip.res, BIG_POSITIVE); + } else { + /* |op1| < |op2| */ + bigXchg(); + bigUsub(); + SET_SIGN(bip.res, BIG_NEGATIVE); + bigXchg(); + } + } + } else { + if (GET_SIGN(bip.op2) == BIG_POSITIVE) { + /* op1 < 0 and op2 >= 0 */ + if (bigUcmp() <= 0) { + /* |op1| <= |op2| */ + bigXchg(); + bigUsub(); + SET_SIGN(bip.res, BIG_POSITIVE); + bigXchg(); + } else { + /* |op1| > |op2| */ + bigUsub(); + SET_SIGN(bip.res, BIG_NEGATIVE); + } + } else { + /* op1 < 0 and op2 < 0 */ + bigUadd(); + SET_SIGN(bip.res, BIG_NEGATIVE); + } + } +} + + +/* + * big integer subtraction + * + * operands in bip.op1 and bip.op2 + * result in bip.res + */ +void bigSub(void) { + if (bip.op1 == NULL || + bip.op2 == NULL) { + nilRefException(); + } + if (GET_SIGN(bip.op1) == BIG_POSITIVE) { + if (GET_SIGN(bip.op2) == BIG_POSITIVE) { + /* op1 >= 0 and op2 >= 0 */ + if (bigUcmp() >= 0) { + /* |op1| >= |op2| */ + bigUsub(); + SET_SIGN(bip.res, BIG_POSITIVE); + } else { + /* |op1| < |op2| */ + bigXchg(); + bigUsub(); + SET_SIGN(bip.res, BIG_NEGATIVE); + bigXchg(); + } + } else { + /* op1 >= 0 and op2 < 0 */ + bigUadd(); + SET_SIGN(bip.res, BIG_POSITIVE); + } + } else { + if (GET_SIGN(bip.op2) == BIG_POSITIVE) { + /* op1 < 0 and op2 >= 0 */ + bigUadd(); + SET_SIGN(bip.res, BIG_NEGATIVE); + } else { + /* op1 < 0 and op2 < 0 */ + if (bigUcmp() <= 0) { + /* |op1| <= |op2| */ + bigXchg(); + bigUsub(); + SET_SIGN(bip.res, BIG_POSITIVE); + bigXchg(); + } else { + /* |op1| > |op2| */ + bigUsub(); + SET_SIGN(bip.res, BIG_NEGATIVE); + } + } + } +} + + +/* + * big integer multiplication + * + * operands in bip.op1 and bip.op2 + * result in bip.res + */ +void bigMul(void) { + if (bip.op1 == NULL || + bip.op2 == NULL) { + nilRefException(); + } + bigUmul(); + if (GET_SIGN(bip.op1) == GET_SIGN(bip.op2) || GET_ND(bip.res) == 0) { + SET_SIGN(bip.res, BIG_POSITIVE); + } else { + SET_SIGN(bip.res, BIG_NEGATIVE); + } +} + + +/* + * big integer division, truncating towards zero + * + * dividend in bip.op1, divisor in bip.op2 + * quotient in bip.res, remainder in bip.rem + */ +void bigDiv(void) { + if (bip.op1 == NULL || + bip.op2 == NULL) { + nilRefException(); + } + bigUdiv(); + if (GET_SIGN(bip.op1) == GET_SIGN(bip.op2) || GET_ND(bip.res) == 0) { + SET_SIGN(bip.res, BIG_POSITIVE); + } else { + SET_SIGN(bip.res, BIG_NEGATIVE); + } + if (GET_SIGN(bip.op1) == BIG_POSITIVE || GET_ND(bip.rem) == 0) { + SET_SIGN(bip.rem, BIG_POSITIVE); + } else { + SET_SIGN(bip.rem, BIG_NEGATIVE); + } +} + + +/**************************************************************/ + +/* big integer conversions */ + + +/* + * conversion int --> big + * + * operand in parameter + * result in bip.res + */ +void bigFromInt(int n) { + int i; + + bip.res = newBig(sizeof(int)); + if (n < 0) { + n = -n; + SET_SIGN(bip.res, BIG_NEGATIVE); + } else { + SET_SIGN(bip.res, BIG_POSITIVE); + } + for (i = 0; i < sizeof(int); i++) { + SET_DIGIT(bip.res, i, n & 0xFF); + n >>= 8; + } + while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ; + SET_ND(bip.res, i + 1); +} + + +/* + * conversion big --> int + * + * operand in bip.op1 + * result is returned + */ +int bigToInt(void) { + int nd; + int i; + int res; + + if (bip.op1 == NULL) { + nilRefException(); + } + nd = GET_ND(bip.op1); + if (nd > 4 || + (nd == 4 && GET_DIGIT(bip.op1, 3) >= 0x80)) { + fatalError("big integer too big for conversion to int"); + } + res = 0; + for (i = nd - 1; i >= 0; i--) { + res <<= 8; + res |= (unsigned int) GET_DIGIT(bip.op1, i); + } + if (GET_SIGN(bip.op1) == BIG_NEGATIVE) { + res = -res; + } + return res; +} + + +/**************************************************************/ + +/* big integer I/O */ + + +/* + * read a big integer + * + * stream to read from in parameter + * result in bip.res + */ +void bigRead(FILE *in) { + int c; + int positive; + + c = fgetc(in); + while (isspace(c)) { + c = fgetc(in); + } + if (c == '-') { + positive = 0; + c = fgetc(in); + } else { + positive = 1; + if (c == '+') { + c = fgetc(in); + } + } + if (!isdigit(c)) { + fatalError("no digits in input"); + } + bigFromInt(10); + bip.rem = bip.res; + bigFromInt(0); + while (isdigit(c)) { + bip.op1 = bip.res; + bip.op2 = bip.rem; + bigUmul(); + bip.op1 = bip.res; + bigFromInt(c - '0'); + bip.op2 = bip.res; + bigUadd(); + c = fgetc(in); + } + ungetc(c, in); + if (positive || GET_ND(bip.res) == 0) { + SET_SIGN(bip.res, BIG_POSITIVE); + } else { + SET_SIGN(bip.res, BIG_NEGATIVE); + } +} + + +/* + * print a big integer + * + * stream to write to in parameter + * number to print in bip.op1 + */ +void bigPrint(FILE *out) { + int nd; + unsigned char r; + int skipZero; + + if (bip.op1 == NULL) { + nilRefException(); + } + nd = GET_ND(bip.op1); + if (nd == 0) { + fprintf(out, "0"); + return; + } + if (GET_SIGN(bip.op1) == BIG_NEGATIVE) { + fprintf(out, "-"); + } + /* number of digits in base 10 = number of digits + in base 256 * log10(256), and log10(256) < 2.5 */ + nd = 2 * nd + nd / 2; + bip.rem = bip.op1; + bigFromInt(10); + bip.op2 = bip.res; + bigFromInt(1); + while (nd != 0) { + bip.op1 = bip.res; + bigUmul(); + nd--; + } + bip.op1 = bip.rem; + bip.op2 = bip.res; + skipZero = 1; + do { + bigUdiv(); + if (GET_ND(bip.res) == 0) { + if (!skipZero) { + fprintf(out, "0"); + } + } else { + if (GET_ND(bip.res) != 1) { + fatalError("internal library error #7 - THIS SHOULD NEVER HAPPEN!"); + } + fprintf(out, "%c", GET_DIGIT(bip.res, 0) + '0'); + skipZero = 0; + } + bip.op1 = bip.rem; + bip.rem = bip.op2; + r = bigUdiv1(10); + bip.op2 = bip.rem; + } while (r == 0); +} + + +/**************************************************************/ + +/* debugging */ + + +/* + * dump a big integer object + */ +void bigDump(FILE *out, BigObjRef bigObjRef) { + int nd; + unsigned char sign; + int i; + + if (bigObjRef == NULL) { + nilRefException(); + } + nd = GET_ND(bigObjRef); + sign = GET_SIGN(bigObjRef); + fprintf(out, "[%d %c", nd, sign == BIG_POSITIVE ? '+' : '-'); + for (i = 0; i < nd; i++) { + fprintf(out, " %02X", GET_DIGIT(bigObjRef, i)); + } + fprintf(out, "]"); +} diff --git a/bigint/src/bigint.h b/bigint/src/bigint.h new file mode 100644 index 0000000..b93d88e --- /dev/null +++ b/bigint/src/bigint.h @@ -0,0 +1,60 @@ +/* + * bigint.h -- big integer library + */ + + +#ifndef _BIGINT_H_ +#define _BIGINT_H_ + + +/* object representation */ +typedef void* BigObjRef; + + +#include + + +typedef struct { + int nd; /* number of digits; array may be bigger */ + /* nd = 0 exactly when number = 0 */ + unsigned char sign; /* one of BIG_NEGATIVE or BIG_POSITIVE */ + /* zero always has BIG_POSITIVE here */ + unsigned char digits[1]; /* the digits proper; number base is 256 */ + /* LS digit first; MS digit is not zero */ +} Big; + +#include "support.h" + + +/* big integer processor registers */ + +typedef struct { + BigObjRef op1; /* first (or single) operand */ + BigObjRef op2; /* second operand (if present) */ + BigObjRef res; /* result of operation */ + BigObjRef rem; /* remainder in case of division */ +} BIP; + +extern BIP bip; /* registers of the processor */ + + +/* big integer processor functions */ + +int bigSgn(void); /* sign */ +int bigCmp(void); /* comparison */ +void bigNeg(void); /* negation */ +void bigAdd(void); /* addition */ +void bigSub(void); /* subtraction */ +void bigMul(void); /* multiplication */ +void bigDiv(void); /* division */ + +void bigFromInt(int n); /* conversion int --> big */ +int bigToInt(void); /* conversion big --> int */ + +void bigRead(FILE *in); /* read a big integer */ +void bigPrint(FILE *out); /* print a big integer */ + +void bigDump(FILE *out, BigObjRef bigObjRef); /* dump a big integer object */ + + +#endif /* _BIGINT_H_ */ diff --git a/bigint/src/bigint.o b/bigint/src/bigint.o new file mode 100644 index 0000000000000000000000000000000000000000..73a86c5f38360b36c6cee5c0753c65bebe10e620 GIT binary patch literal 28344 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 EKQ1+h-2eap literal 0 HcmV?d00001 diff --git a/bigint/src/support.h b/bigint/src/support.h new file mode 100644 index 0000000..8e4455e --- /dev/null +++ b/bigint/src/support.h @@ -0,0 +1,15 @@ +/* + * support.h -- object representation and support functions + */ + + +#ifndef _SUPPORT_H_ +#define _SUPPORT_H_ + +/* support functions */ + +void fatalError(char *msg); /* print a message and exit */ +void * newPrimObject(int dataSize); /* create a new primitive object */ +void * getPrimObjectDataPointer(void * primObject); + +#endif /* _SUPPORT_H_ */ diff --git a/bigint/tst/Makefile b/bigint/tst/Makefile new file mode 100644 index 0000000..67ca0eb --- /dev/null +++ b/bigint/tst/Makefile @@ -0,0 +1,28 @@ +# +# Makefile for big integer test +# + +BUILD = ../build + +CC = gcc +CFLAGS = -g -Wall -I$(BUILD)/include +LDFLAGS = -g -Wall -L$(BUILD)/lib +LDLIBS = -lbigint + +all: testbip + +install: all + mkdir -p $(BUILD)/bin + cp testbip $(BUILD)/bin + +testbip: testbip.o support.o + $(CC) $(LDFLAGS) -o testbip testbip.o support.o $(LDLIBS) + +testbip.o: testbip.c + $(CC) $(CFLAGS) -o testbip.o -c testbip.c + +support.o: support.c + $(CC) $(CFLAGS) -o support.o -c support.c + +clean: + rm -f *~ testbip.o support.o testbip diff --git a/bigint/tst/support.c b/bigint/tst/support.c new file mode 100644 index 0000000..b036b1e --- /dev/null +++ b/bigint/tst/support.c @@ -0,0 +1,55 @@ +/* + * support.c -- support functions for big integer library + */ + + +#include +#include + +#include "support.h" + +typedef struct { + unsigned int size; /* byte count of payload data */ + unsigned char data[1]; /* payload data, size as needed */ +} *ObjRef; + + +/* + * This routine is called in case a fatal error has occurred. + * It should print the error message and terminate the program. + */ +void fatalError(char *msg) { + printf("Fatal error: %s\n", msg); + exit(1); +} + + +/* + * This function is called whenever a new primitive object with + * a certain amount of internal memory is needed. It should return + * an object reference to a regular object, which contains a freely + * usable memory area of at least the requested size (measured in + * bytes). The memory area need not be initialized in any way. + * + * Note that this function may move all objects in memory at will + * (due to, e.g., garbage collection), as long as the pointers in + * the global "bip" structure point to the correct objects when + * the function returns. + */ +void * newPrimObject(int dataSize) { + ObjRef bigObjRef; + + bigObjRef = malloc(sizeof(unsigned int) + + dataSize * sizeof(unsigned char)); + if (bigObjRef == NULL) { + fatalError("newPrimObject() got no memory"); + } + bigObjRef->size = dataSize; + return bigObjRef; +} + +void * getPrimObjectDataPointer(void * obj){ + ObjRef oo = ((ObjRef) (obj)); + return oo->data; +} + diff --git a/bigint/tst/support.o b/bigint/tst/support.o new file mode 100644 index 0000000000000000000000000000000000000000..859a1a129113a3be4b939990b0c1b015c2bd8dad GIT binary patch literal 4832 zcmbtWd010d7QZ0~6%Zp;1X+xrOhC;9uyvyv1vI5}q&hH66-@#Uq-HY&1S=m1E`+6m zpi)bfsjaw9D=ONLX^To-Fx3{O>P)R;^($hBajDCo^(%AF%e~=w$^0{OzVE$z&hMPx zx!Za7zM}ZVc`hOmq9Q`G(11lzgrvg;bS1AU(P-q0l2z6pRi(WWm9?->RT1B(vYu8| z4S@ia^~`Z-d*Jm2HS#Zjpscvy2w0 z!6?;pdZW1jIp%tXOq$L;zhS2BY+GAL+u0MyRXumBXjr0Bd${<8-79XSD9dX~gWA(G zM2i{%DLkGv%Wh~jU)d&#-V!~ij~L-`e2#9n+b0F;SN9x>39P)@(CVjr zM|?jn&|j@vdOuCQ?cQq9-bG4V)_PMw=-BfwRj-XMcD=Hudr0D%VCB;n%MQBx{NV0c zq`AQjS^fU>D$(xE6KZSR+iQmmJ?7%?;#Hy!t(qQFU83|zh`wMIMPyuD(4kdaLgDJ| ze&gzPUTj-_GRMPqUM+Fkzi9q9cRVi78oejY^@F()!w!Vb8)^IYdWpZ(t-GT6#FT)O zFCD(++Z0_^zD+qQ3NOjharKUM`NN=f(Qj(?DN#t`@A`!HbVQdce7&M)&Ctu@f{y;U zE%5E4@7Br6)3@jz_wERIv*d{_1T{#Otgdodw{E&yc%12a=w)5P?f06;FTU&VXSluj zSlNMs+NnR))w-n({UNupRtPoz2D7z#pm(C;T;EG?hI*9tJROc*_wH5t19Bf%Gsa(wdm=!&P7ii6~ z*}n!~irmrB5*!F+II!OeyXlx`enXc=tyXK1$lEPLu~sw_q0#y1jKg0sD1Jp2j_0nc zO|G4lm6cyS$)7Vaw9MVNIxAD@l34k3;ewL}96%-?VqtH*6u52W+j=yASVE zc-qpp{H?8H?1hfU>$e=OOYZZZcsVX*o-rjzoU)@kGv#zEk|SH~HH*tK`D4pVv&TpLR%gB>VD# zOU?V5y!$7lF0Lt<8*(x);O@=q5ue($@4cq&`S{lxZ-0{1B3aPC==0&TKOEP-ap&+W zs}@{uz7>$>HSKQ?xTR5t&2$>Gw-XnB-8QW~X*idIZhMDinZ#cwHo;7G$k$OVbo z0HY!zHr=O@#35R}5Q*|7q5v=V7pk$-596c+5ubUEw`7A$>@YWiPb0i|XsORdiP`r4 zQ;C0!(4Wk^iN|>Z<8np!`<;2kj$L@(E9PhWJO-8+!Dt7I7~w%W5i#;~f_W zBX5CaS0RIsV4U_{LHOoDNHQoIp`ibQhmbs!&#yDa;2dz4XDW%$!z~EE?x5u4noLHs zMV^i_;i`#;n+BQ8*#=7{;_|aC&tEu5uhHp@=_re{4BSF-n3!b549?8Y1Jb(SM~t6m z{dNfj5DV0r2Yx6%89*$6!`e{%RRFO74y#M?#QAoysaJs)p zo>QQ=XtcPsnCRMsDHqEl8e$k3J;V=Hwu`*=RR-Zw9B$&03ai$TZ>@Ue{=~ zW-bqh0hvH%jUkHz>Hwz8HgJ@J`=ctr%XmB8sMm7_+_k}I;pF%VpPXaSq^}@$mLXSe zG8;{t*-}9Aa?6)xnl*ZkO!WV3q?iwDE%fKD1fl07)FcBRLAK`V{O~;!FLuuIKZ2b2K zpPfI;hyOlj4KOY8#1^hx``SsYz^Myg6lb@SF2B-bf z_D|SPbzx|r@aIV2U}FzqAAG88{Ywd-?jKD-$4~8ZSb>}@KZ)@3X&`A?emlmU?H}^8 z6I6r;^#lKMlu!51S>Hf8OZunx_b7}xt3SZlvjg}Fa(*R&ArN-`Mqr;azKV>$OTYz{ G<^Kn6AHA{w literal 0 HcmV?d00001 diff --git a/bigint/tst/testbip b/bigint/tst/testbip new file mode 100755 index 0000000000000000000000000000000000000000..6d9fe44d411bc478834bf1b1d7e6dbe40cf7d3f4 GIT binary patch literal 60832 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 literal 0 HcmV?d00001 diff --git a/bigint/tst/testbip.c b/bigint/tst/testbip.c new file mode 100644 index 0000000..7c65754 --- /dev/null +++ b/bigint/tst/testbip.c @@ -0,0 +1,1253 @@ +/* + * testbip.c -- test the big integer processor + */ + + +#include +#include +#include + +#include "bigint.h" + +typedef struct { + unsigned int size; /* byte count of payload data */ + unsigned char data[1]; /* payload data, size as needed */ +} *ObjRef; + +/**************************************************************/ + + +void dump(char *prefix, ObjRef x, char *suffix) { + if (prefix != NULL && *prefix != '\0') { + printf("%s", prefix); + } + bigDump(stdout, x); + if (suffix != NULL && *suffix != '\0') { + printf("%s", suffix); + } +} + + +/**************************************************************/ + + +void test00(void) { + bigFromInt(0); + dump("+0x00000000 = ", bip.res, "\n"); + + bigFromInt(1); + dump("+0x00000001 = ", bip.res, "\n"); + + bigFromInt(2); + dump("+0x00000002 = ", bip.res, "\n"); + + bigFromInt(0x12); + dump("+0x00000012 = ", bip.res, "\n"); + + bigFromInt(0x123); + dump("+0x00000123 = ", bip.res, "\n"); + + bigFromInt(0x1234); + dump("+0x00001234 = ", bip.res, "\n"); + + bigFromInt(0x12345); + dump("+0x00012345 = ", bip.res, "\n"); + + bigFromInt(0x123456); + dump("+0x00123456 = ", bip.res, "\n"); + + bigFromInt(0x1234567); + dump("+0x01234567 = ", bip.res, "\n"); + + bigFromInt(0x12345678); + dump("+0x12345678 = ", bip.res, "\n"); + + bigFromInt(-0); + dump("-0x00000000 = ", bip.res, "\n"); + + bigFromInt(-1); + dump("-0x00000001 = ", bip.res, "\n"); + + bigFromInt(-2); + dump("-0x00000002 = ", bip.res, "\n"); + + bigFromInt(-0x12); + dump("-0x00000012 = ", bip.res, "\n"); + + bigFromInt(-0x123); + dump("-0x00000123 = ", bip.res, "\n"); + + bigFromInt(-0x1234); + dump("-0x00001234 = ", bip.res, "\n"); + + bigFromInt(-0x12345); + dump("-0x00012345 = ", bip.res, "\n"); + + bigFromInt(-0x123456); + dump("-0x00123456 = ", bip.res, "\n"); + + bigFromInt(-0x1234567); + dump("-0x01234567 = ", bip.res, "\n"); + + bigFromInt(-0x12345678); + dump("-0x12345678 = ", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test01(void) { + bigFromInt(0); + bip.op1 = bip.res; + printf("sign(+0x00000000) = %d\n", bigSgn()); + + bigFromInt(1); + bip.op1 = bip.res; + printf("sign(+0x00000001) = %d\n", bigSgn()); + + bigFromInt(2); + bip.op1 = bip.res; + printf("sign(+0x00000002) = %d\n", bigSgn()); + + bigFromInt(0x12); + bip.op1 = bip.res; + printf("sign(+0x00000012) = %d\n", bigSgn()); + + bigFromInt(0x123); + bip.op1 = bip.res; + printf("sign(+0x00000123) = %d\n", bigSgn()); + + bigFromInt(0x1234); + bip.op1 = bip.res; + printf("sign(+0x00001234) = %d\n", bigSgn()); + + bigFromInt(0x12345); + bip.op1 = bip.res; + printf("sign(+0x00012345) = %d\n", bigSgn()); + + bigFromInt(0x123456); + bip.op1 = bip.res; + printf("sign(+0x00123456) = %d\n", bigSgn()); + + bigFromInt(0x1234567); + bip.op1 = bip.res; + printf("sign(+0x01234567) = %d\n", bigSgn()); + + bigFromInt(0x12345678); + bip.op1 = bip.res; + printf("sign(+0x12345678) = %d\n", bigSgn()); + + bigFromInt(-0); + bip.op1 = bip.res; + printf("sign(-0x00000000) = %d\n", bigSgn()); + + bigFromInt(-1); + bip.op1 = bip.res; + printf("sign(-0x00000001) = %d\n", bigSgn()); + + bigFromInt(-2); + bip.op1 = bip.res; + printf("sign(-0x00000002) = %d\n", bigSgn()); + + bigFromInt(-0x12); + bip.op1 = bip.res; + printf("sign(-0x00000012) = %d\n", bigSgn()); + + bigFromInt(-0x123); + bip.op1 = bip.res; + printf("sign(-0x00000123) = %d\n", bigSgn()); + + bigFromInt(-0x1234); + bip.op1 = bip.res; + printf("sign(-0x00001234) = %d\n", bigSgn()); + + bigFromInt(-0x12345); + bip.op1 = bip.res; + printf("sign(-0x00012345) = %d\n", bigSgn()); + + bigFromInt(-0x123456); + bip.op1 = bip.res; + printf("sign(-0x00123456) = %d\n", bigSgn()); + + bigFromInt(-0x1234567); + bip.op1 = bip.res; + printf("sign(-0x01234567) = %d\n", bigSgn()); + + bigFromInt(-0x12345678); + bip.op1 = bip.res; + printf("sign(-0x12345678) = %d\n", bigSgn()); +} + + +/**************************************************************/ + + +void test02(void) { + int m[7]; + ObjRef n[7]; + int i, j; + int res; + + m[0] = 0; + bigFromInt(m[0]); + n[0] = bip.res; + printf("n[0] = %d\n", m[0]); + + m[1] = 100; + bigFromInt(m[1]); + n[1] = bip.res; + printf("n[1] = %d\n", m[1]); + + m[2] = -100; + bigFromInt(m[2]); + n[2] = bip.res; + printf("n[2] = %d\n", m[2]); + + m[3] = 101; + bigFromInt(m[3]); + n[3] = bip.res; + printf("n[3] = %d\n", m[3]); + + m[4] = -101; + bigFromInt(m[4]); + n[4] = bip.res; + printf("n[4] = %d\n", m[4]); + + m[5] = 12345678; + bigFromInt(m[5]); + n[5] = bip.res; + printf("n[5] = %d\n", m[5]); + + m[6] = -12345678; + bigFromInt(m[6]); + n[6] = bip.res; + printf("n[6] = %d\n", m[6]); + + for (i = 0; i < 7; i++) { + for (j = 0; j < 7; j++) { + printf("%12d ", m[i]); + bip.op1 = n[i]; + bip.op2 = n[j]; + res = bigCmp(); + if (res < 0) { + printf("<"); + } else + if (res > 0) { + printf(">"); + } else { + printf("="); + } + printf(" %12d", m[j]); + printf("\n"); + } + } +} + + +/**************************************************************/ + + +void test03(void) { + bigFromInt(0); + bip.op1 = bip.res; + bigNeg(); + dump("+n = ", bip.op1, "\n"); + dump("-n = ", bip.res, "\n"); + + bigFromInt(1); + bip.op1 = bip.res; + bigNeg(); + dump("+n = ", bip.op1, "\n"); + dump("-n = ", bip.res, "\n"); + + bigFromInt(-1); + bip.op1 = bip.res; + bigNeg(); + dump("+n = ", bip.op1, "\n"); + dump("-n = ", bip.res, "\n"); + + bigFromInt(0x12345678); + bip.op1 = bip.res; + bigNeg(); + dump("+n = ", bip.op1, "\n"); + dump("-n = ", bip.res, "\n"); + + bigFromInt(-0x12345678); + bip.op1 = bip.res; + bigNeg(); + dump("+n = ", bip.op1, "\n"); + dump("-n = ", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test04(void) { + int m[6]; + ObjRef n[6]; + int i, j; + + m[0] = +0x12345679; + m[1] = +0x12345678; + m[2] = +0x12345677; + m[3] = -0x12345677; + m[4] = -0x12345678; + m[5] = -0x12345679; + + for (i = 0; i < 6; i++) { + bigFromInt(m[i]); + n[i] = bip.res; + } + + for (i = 0; i < 6; i++) { + for (j = 0; j < 6; j++) { + bip.op1 = n[i]; + bip.op2 = n[j]; + bigAdd(); + printf("%12d + %12d = ", m[i], m[j]); + dump("", bip.res, "\n"); + } + } +} + + +/**************************************************************/ + + +void test05(void) { + int m[5]; + ObjRef n[5]; + int i, j; + + m[0] = +0x12345678; + m[1] = +1; + m[2] = 0; + m[3] = -1; + m[4] = -0x12345678; + + for (i = 0; i < 5; i++) { + bigFromInt(m[i]); + n[i] = bip.res; + } + + for (i = 0; i < 5; i++) { + for (j = 0; j < 5; j++) { + bip.op1 = n[i]; + bip.op2 = n[j]; + bigAdd(); + printf("%12d + %12d = ", m[i], m[j]); + dump("", bip.res, "\n"); + } + } +} + + +/**************************************************************/ + + +void test06(void) { + int m[6]; + ObjRef n[6]; + int i, j; + + m[0] = +0x12345679; + m[1] = +0x12345678; + m[2] = +0x12345677; + m[3] = -0x12345677; + m[4] = -0x12345678; + m[5] = -0x12345679; + + for (i = 0; i < 6; i++) { + bigFromInt(m[i]); + n[i] = bip.res; + } + + for (i = 0; i < 6; i++) { + for (j = 0; j < 6; j++) { + bip.op1 = n[i]; + bip.op2 = n[j]; + bigSub(); + printf("%12d - %12d = ", m[i], m[j]); + dump("", bip.res, "\n"); + } + } +} + + +/**************************************************************/ + + +void test07(void) { + int m[5]; + ObjRef n[5]; + int i, j; + + m[0] = +0x12345678; + m[1] = +1; + m[2] = 0; + m[3] = -1; + m[4] = -0x12345678; + + for (i = 0; i < 5; i++) { + bigFromInt(m[i]); + n[i] = bip.res; + } + + for (i = 0; i < 5; i++) { + for (j = 0; j < 5; j++) { + bip.op1 = n[i]; + bip.op2 = n[j]; + bigSub(); + printf("%12d - %12d = ", m[i], m[j]); + dump("", bip.res, "\n"); + } + } +} + + +/**************************************************************/ + + +void test08(void) { + int i; + + bigFromInt(1); + for (i = 1; i < 100; i++) { + bip.op1 = bip.res; + bip.op2 = bip.res; + bigAdd(); + printf("2 ^ %2d = ", i); + dump("", bip.res, "\n"); + } +} + + +/**************************************************************/ + + +void test09(void) { + int i, j; + + bigFromInt(2); + bip.op2 = bip.res; + for (i = 1; i < 10; i++) { + bip.res = bip.op2; + for (j = 1; j < i * i; j++) { + bip.op1 = bip.res; + bigMul(); + } + printf("2 ^ (%d ^ 2) = ", i); + dump("", bip.res, "\n"); + } +} + + +/**************************************************************/ + + +void factorial(int n) { + bigFromInt(1); + while (n > 0) { + bip.op1 = bip.res; + bigFromInt(n); + bip.op2 = bip.res; + bigMul(); + n--; + } +} + + +void test10(void) { + int i; + + for (i = 0; i < 100; i++) { + factorial(i); + printf("%2d! = ", i); + dump("", bip.res, "\n"); + } +} + + +/**************************************************************/ + + +void test11(void) { + int n, m; + + n = 5; + m = 0; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); +} + + +/**************************************************************/ + + +void test12(void) { + int n, m; + + n = 12; + m = 12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345677; + m = 12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12; + m = 12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345677; + m = 12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12; + m = -12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345677; + m = -12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12; + m = -12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345677; + m = -12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); +} + + +/**************************************************************/ + + +void test13(void) { + int n, m; + + n = 12345678; + m = 1; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345678; + m = 17; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345678; + m = 255; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = 1; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = 17; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = 255; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345678; + m = -1; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345678; + m = -17; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345678; + m = -255; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = -1; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = -17; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = -255; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); +} + + +/**************************************************************/ + + +void test14(void) { + int n, m; + ObjRef dividend; + ObjRef divisor; + int ok; + + printf("divisor"); + for (m = 0; m < 256; m++) { + if (m % 8 == 0) { + printf("\n%3d to %3d: ", m, m + 7); + } + if (m == 0) { + printf(" "); + fflush(stdout); + continue; + } + bigFromInt(m); + divisor = bip.res; + ok = 1; + for (n = 0; n < (1 << 18); n++) { + bigFromInt(n); + dividend = bip.res; + bip.op1 = dividend; + bip.op2 = divisor; + bigDiv(); + bip.op1 = bip.res; + bigMul(); + free(bip.op1); + bip.op1 = bip.res; + bip.op2 = bip.rem; + bigAdd(); + free(bip.op1); + free(bip.op2); + bip.op1 = bip.res; + bip.op2 = dividend; + if (bigCmp() != 0) { + ok = 0; + } + free(bip.op1); + free(dividend); + } + free(divisor); + printf("%c", ok ? '.' : '?'); + fflush(stdout); + } + printf("\n"); +} + + +/**************************************************************/ + + +void test15(void) { + int n, m; + + n = 123456789; + m = (0xFF << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x80 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x7F << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x55 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x2F << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x18 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x0A << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x03 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x02 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x01 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); +} + + +/**************************************************************/ + + +void test16(void) { + int n1, n2, n3, m; + + n1 = 0x12345678; + n2 = 0x66554433; + n3 = 12; + bigFromInt(n1); + bip.op1 = bip.res; + bigFromInt(n2); + bip.op2 = bip.res; + bigMul(); + bip.op1 = bip.res; + bigFromInt(n3); + bip.op2 = bip.res; + bigMul(); + bip.op1 = bip.res; + m = 0x5764; + bigFromInt(m); + bip.op2 = bip.res; + dump("", bip.op1, " / "); + dump("", bip.op2, " =\n"); + bigDiv(); + dump("", bip.res, " R. "); + dump("", bip.rem, "\n"); + bip.op1 = bip.res; + bigMul(); + bip.op1 = bip.res; + bip.op2 = bip.rem; + bigAdd(); + dump("quotient * divisor + remainder =\n", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test17(void) { + /* prepare two big integers with 8 and 4 digits, respectively */ + bigFromInt(0x11111111); + bip.op1 = bip.res; + bip.op2 = bip.res; + bigMul(); + bip.op1 = bip.res; + /* set all 8 digits of dividend */ + ((ObjRef) bip.op1)->data[5 + 0] = 0xF2; + ((ObjRef) bip.op1)->data[5 + 1] = 0xFB; + ((ObjRef) bip.op1)->data[5 + 2] = 0xE3; + ((ObjRef) bip.op1)->data[5 + 3] = 0x46; + ((ObjRef) bip.op1)->data[5 + 4] = 0x7C; + ((ObjRef) bip.op1)->data[5 + 5] = 0xC2; + ((ObjRef) bip.op1)->data[5 + 6] = 0x54; + ((ObjRef) bip.op1)->data[5 + 7] = 0xF8; + /* set )all 4 digits of divisor */ + ((ObjRef) bip.op2)->data[5 + 0] = 0x1B; + ((ObjRef) bip.op2)->data[5 + 1] = 0xE8; + ((ObjRef) bip.op2)->data[5 + 2] = 0xE7; + ((ObjRef) bip.op2)->data[5 + 3] = 0x8D; + /* divide */ + dump("", bip.op1, " / "); + dump("", bip.op2, " =\n"); + bigDiv(); + dump("", bip.res, " R. "); + dump("", bip.rem, "\n"); + /* verify */ + bip.op1 = bip.res; + bigMul(); + bip.op1 = bip.res; + bip.op2 = bip.rem; + bigAdd(); + dump("quotient * divisor + remainder =\n", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test18(void) { + /* prepare two big integers with 8 and 4 digits, respectively */ + bigFromInt(0x11111111); + bip.op1 = bip.res; + bip.op2 = bip.res; + bigMul(); + bip.op1 = bip.res; + /* set all 8 digits of dividend */ + ((ObjRef) bip.op1)->data[5 + 0] = 0x4D; + ((ObjRef) bip.op1)->data[5 + 1] = 0xCC; + ((ObjRef) bip.op1)->data[5 + 2] = 0x8C; + ((ObjRef) bip.op1)->data[5 + 3] = 0x18; + ((ObjRef) bip.op1)->data[5 + 4] = 0x34; + ((ObjRef) bip.op1)->data[5 + 5] = 0xDF; + ((ObjRef) bip.op1)->data[5 + 6] = 0x1D; + ((ObjRef) bip.op1)->data[5 + 7] = 0xFD; + /* set all 4 digits of divisor */ + ((ObjRef) bip.op2)->data[5 + 0] = 0x69; + ((ObjRef) bip.op2)->data[5 + 1] = 0xF4; + ((ObjRef) bip.op2)->data[5 + 2] = 0x94; + ((ObjRef) bip.op2)->data[5 + 3] = 0x37; + /* divide */ + dump("", bip.op1, " / "); + dump("", bip.op2, " =\n"); + bigDiv(); + dump("", bip.res, " R. "); + dump("", bip.rem, "\n"); + /* verify */ + bip.op1 = bip.res; + bigMul(); + bip.op1 = bip.res; + bip.op2 = bip.rem; + bigAdd(); + dump("quotient * divisor + remainder =\n", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test19(void) { + int n, m; + + n = 0x7FFFFFFF; + bigFromInt(n); + bip.op1 = bip.res; + m = bigToInt(); + printf("%12d = %12d\n", n, m); + + n = 0x00000001; + bigFromInt(n); + bip.op1 = bip.res; + m = bigToInt(); + printf("%12d = %12d\n", n, m); + + n = 0x00000000; + bigFromInt(n); + bip.op1 = bip.res; + m = bigToInt(); + printf("%12d = %12d\n", n, m); + + n = -0x00000001; + bigFromInt(n); + bip.op1 = bip.res; + m = bigToInt(); + printf("%12d = %12d\n", n, m); + + n = -0x7FFFFFFF; + bigFromInt(n); + bip.op1 = bip.res; + m = bigToInt(); + printf("%12d = %12d\n", n, m); +} + + +/**************************************************************/ + + +void test20(void) { + printf("please enter a number: "); + fflush(stdout); + bigRead(stdin); + dump("", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test21(void) { + bigFromInt(0); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(1); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(-1); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(0x1234); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(-0x1234); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(0x186A0); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(-0x186A0); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(0x12345678); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(-0x12345678); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(987654321); + bip.op1 = bip.res; + bip.op2 = bip.res; + bigMul(); + bip.op1 = bip.res; + bip.op2 = bip.res; + bigMul(); + dump("", bip.res, " =\n"); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); +} + + +/**************************************************************/ + + +typedef struct { + void (*func)(void); + char *explanation; +} TestFunc; + + +TestFunc tests[] = { + { test00, "representation" }, + { test01, "sign" }, + { test02, "comparison" }, + { test03, "negation" }, + { test04, "addition, equal sizes" }, + { test05, "addition, different sizes" }, + { test06, "subtraction, equal sizes" }, + { test07, "subtraction, different sizes" }, + { test08, "2^n by addition" }, + { test09, "2^(n^2) by multiplication" }, + { test10, "factorial" }, + { test11, "division by zero" }, + { test12, "division, small dividend" }, + { test13, "division, single digit divisor" }, + { test14, "division, systematic test of simple cases" }, + { test15, "division, general case, different scale factors" }, + { test16, "division, general case, qhat (first guess)" }, + { test17, "division, general case, qhat (decremented twice)" }, + { test18, "division, general case, qhat (final correction)" }, + { test19, "conversion big --> int" }, + { test20, "read from file" }, + { test21, "print to file" }, +}; + +int numTests = sizeof(tests) / sizeof(tests[0]); + + +/**************************************************************/ + + +void usage(char *myself) { + int i; + + printf("Usage: %s \n", myself); + printf("valid test numbers are:\n"); + for (i = 0; i < numTests; i++) { + printf(" %2d: %s\n", i, tests[i].explanation); + } + exit(1); +} + + +int main(int argc, char *argv[]) { + int testNumber; + char *endp; + + if (argc != 2) { + usage(argv[0]); + } + testNumber = strtol(argv[1], &endp, 0); + if (*endp != '\0') { + usage(argv[0]); + } + if (testNumber < 0 || testNumber >= numTests) { + usage(argv[0]); + } + printf("Test %d: %s\n", testNumber, tests[testNumber].explanation); + (*tests[testNumber].func)(); + return 0; +} diff --git a/bigint/tst/testbip.o b/bigint/tst/testbip.o new file mode 100644 index 0000000000000000000000000000000000000000..7c17fd5ecea50336f37b1510c865dee15d1db8b6 GIT binary patch literal 62728 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%0DLBL{Ff_#E;p@{_QYmtBl7~&id-=`88~dV(PMsxf z?-QUORg_1Kq)%vwXJ7XqQ?FjZA?}|2dwKTl->Z+iub(cfBxSDNKKfB*dDOtmOFycj zKUCFxLp}7PYWhQU{h@|D*DBP{l<*ObjL_LhJMFB6)Yx~BepFF^sH8tsHudS_7aH8x z)F;T>TSrx7u)+F%RsBKl&ROryS?jJtpd7aBrlONfk8gksqMi7BLx)M7$xY4!xl|Hw zETP!sQ?`5#BHms?u}QsLDv1Y6C^o4_|IrePjr-5gvBu?6Nj}kvOCPx;s^!@9190iD zNB`vut$)<7n10%}K|RWTGl(DZ-w7Q1J)k)6_c!3!?>WZl8o37k*zbMd*zZ&D!ST}d zMB}3IegeIWr?5Jf>z>^Bczqu6W<1Gjr$6JzdN4-0fT;Jrz`>g>S`>hW?INqkf zvER0g(|qj${+MUEj!`_=Z$I$Ceg^`_eupvMQnxjQgFp5=6*%@g8+@?e1;DZ2<&1Yz z{r&|0*zYgEvEM!5gZ&-?j{Tlyyr1g#68K}kcYtHRvEYOKJ_nBdzGr-h>Nk~~m}2Ae zDkE_0H@o6|KIa9F{T5@Kp6|*k&ikzb9Q&;eJ~-Y+z_H&}jL+4FX>tR9%yTc`*l!>3 z!G8ULW50tLU!nRP1^(D?1aRy(3Vg8NxxlgC9~s}G`dtP7*zYFb*zXST!G8Ax$9|79 z{;TTu9Qb3uH-KZm_rM4HeF7Z&eZx3CPkaJ@>^Hq^EH*jcu-`0-%VyZ`cfhgV!i@hR zO~qDHaXz1&fn&e)I-B=fkNMN{Q8UJ0>fM^!fG!SU_}E_bQlBa9bP<2|i7 z@Ao!v?Drw~V83yU)BVz);FC?nLp&bza<{ySCxZ+`Z1Mr`CvyPDc=9RE^IwE<>bC^= zU_2E-FXOSOcxriDxM{v$9UEP$9Oh@55}{Daf)Xz_+UIoK`-N>`=<+_$9Qf5$9Nuq z561J1af;^^_+UIAK`-N>`!HMiUar{WX^ba3aEvFf;(R`v8K-z0zz5@T1ig%Bx2jhy z&|^Fn;22L!@WK4FXPn~c3_ci-JLqLR+I!UEF#z-!PZ)5FXB7BgJQEnFc=T_)>-ooc zW`kbF^GxOEN9Y&hSpyv7*$6%u&vwQso;~1$@f-oYj3=#}0Af22dW`2LaE#|Z_+UIw z8K-z&f)B>?0rWDSf-0W$>MbEYpR)nSc=9OD=W}7kDW2lsgYlFHy^M$Mr)z>9^V1kO z#?u0PFhA`Wr+7Mn5606Q^fDg0FZTyM#xoc=#xoLpFrM*@Q#_Nw2jiIqdKr(ms@G!B zV?3*YV>}zc2jkhsIK{IYd@!EFpqKHCQ1P4tJ;rkbIL31id@!CTj8i->zz5@b4|*BT z92HMG_4xsx&sl+EJh>I;^SKb?6i+em!FbAnUdHp2il+wXF+YufV?52l2lLaGaf+uS z_+UJ}KriDtq~h@dJ;pN#IL0#qd@!DIj8i-j;DhnZ1ig%hUSItHdW>fkaExa?_+UK0 zFi!F80w0X$5a?w*^g8W#&|^HGfMYyqY(-E!<^KkJ&_A7gQ7SfB7xd4pIInL(;L^IW@-G8E=wAys`Zok0jK3XlX-%KQ z_5vUDk6`+)DxU8R^#1|9?3b>WZH&u&$Za?H}Ie0w3&m1ml#SvEYOGi7?Pd0mt~~ zGfw$g0{)nvRiMW>*8@lY9gI_c4jA~K0FL=N2R_*ERmLelx4;MU^T0s=3^>OBmT}6@ z7x2gYq*EWf@_C*aIQr*iobppxaejRb2afp(2OrGOZpJA;rx>T_uXErpzk)*gIMB=Z zgXAxy} zYw*YX*vrnuM(ZTyr-0(JJ?5tv=rNu$z%f6S8K?Zz27jD~zQ8d*hk(mn8t)0kdA-uf z;KW9p^tlI)1!Kh+th{M1pL=chC1F+bj*$Ncz#9^(lHj`}Iu29Ei;2>uw)4aRBy++&>b`Gj%G+Y80zFIOVN0_+#Fh0muBb0UyjyC&p>KJ_bC1af*MW0Uyse<$to`vOlx< zA-){+G7m8-pBq7s`P>eA9M?YJn9pO3Q$BwOf6V6_;F!&Dxe++# zVLSL>zxx=cd>%9KIm`5v&&!NcK5u|eamd?K(97{|R(X35dd!+AZh=4MEsp7_jvqmf z@z|)s(Y&HMW&n=yez*Gs$);^!8-bb z9_u(1^q99XpvU+p0mr<}WSsIgAN;Y7tC*hZxE1sm&u-Amc+{ckSKt`WDaI+Di;D9) z#sSAVz5yT1Lp$OKj2~eKIRf^N{M8lX0qJUhu&>mI6K2u?pxhZ?!>>@izjF zd27Wu<;@NJv5sC$Pjws!dWQ#|t>tu|N1=9)cLBIu1AR31@n$<7CFEj?=*h>$nK? zSjRP>$GmL>J;uKsIOgpj z3OLrWgyMWXEYCRAv6_KTU8bixS{SD~HU}T9V;9h49s7VD^X3nFtYZjp%-cxDDQ^?N zAL}@W>8XxOK#%dP0zKAoJ#dU?2jdja0r1Cot^&t8-T@!XLoDM|$5#eE@0p(JXv(9{ zE1D-%$Fz#eW2|FN&|@8ofFAQ!3iKF%1>l&s8jMrk8h}6Mtqs#t9eaQttSg#pQS~p2DEVI+g&A@i;L~@l*$YjHerLtfL3` zU>-ZEn#`72B6whby$9Qt()23CD*9!#|r*)6=Uz~BOqoaXO6{aVj+Kf{j z8-Neiu?^_4jy*t+dGi82*0Dcu%v&hql(!M!k9nKI^i;=rpvQO?gC6VnAK)0z2F59# z?ck5`oCS{8<7M!{JltZO>iEdO=LOSK9p5reb&LletYgOf`h25xjNZ@5qquC3c`FQh zjK2hM%$pPAl(*{Ok9lj#^i;zZ#MG7Lb1`j zqB`0u&gWGw&|@770>^ktGEVVS0Dp|9DR8W#EBIg@+!&`i_A>D4!}L@~f5xefLEwXR z90Pi+<22A?9p``^B0zKW1f|>X^^KrwG$i9ZNAzbu14)SjXC+$2v9xJ?5Ua5~8Oc{Vf3TNwDXV|uD%7sjcMJ;4X-=ns0V<519J-o}6)I{peA<2l7R#d8t-F`hW!SjRWugL#N&oa&g)EP@l8tOxpJ zHcOiHbNQTR4O>62r#j|UTpnW`OMxEiSOxT$x7wh`_!|MoytQJS^5zEqm^Uw`r#cP< zJ;oCTdaUCp;22K?;}p*f@W*&o0muBW2OrGCFN{+i_Z#>eWqP_EPcu$+JP$rt$Gf1% zI=%os=It%$G5*iMF>ki=%Qs?^>z?G4x2%fG_%LsUnV#xc4)hpLCD3CXYXZl38Z%Du zv;=>Q#|t>tu|N1=9)cLBIu1AR31@n$<7CFEj?=*h>$nK?SjRP>$GmL>J;uKsIOgpj zhQQ(91+F+pHW}rX9IK}fj<22tcfj`c- zn@msh_CDj}{}_DCFy5C2`uCtO4SG{CaUeDu@q>9t&p7p)g>ibm{*G}PZ$8E4v3!e{ ze2OqV@zS8jIGvcD{Hq)2>oGm$vkBwWZ(GL6za#j|uTYV`FVhnr0D6pnxB;JMz&8TN z`M+IpSudRb`$3QM|2lB=`2rlTi*&_>vDo;0$jms6H@D(4U+7ba=_&sXjLUX%E2FqP zmb>I%Lva~TYVkww<23<2t~0GbkMp?$aOp$;{;ntEwC?o*e_V${nV#0+v7pCzB0!Jp za1?NiXFlT;&l2#*cvdm}Q)wo)4WKV8jwzqN0mpis0UylUCC16;j)6}s(^K7_GoD6^ z(qwuKK601*Q#;(Rp=Xy*}b#DoJjHf;5vF=@g zV?17rQ#^j)kMRUEJ=J{}=&|mzfMea~gAeBIN5-ixYYcogGCkFOJL6RMJ>Y|NKM8u7 zAG+SJf*$jH2lNFAf~zab%q0sS5rW zPaUSGx?4bxb?*Tj>+S_Un796nQ{6)ie1~pSMbL?pJRHe`)$x;JP$#Sb&ms%@w{W4;xU!f=bOwI#*5Oiy)R4SI}c1L(2t+kj&{2N;4XWFmGQNr@Cj5 zH<4nK^+TVmiu3!!+>BG*3xE&Sy)5Xl?$tq$d9DX~jK2wR%yS#YDbJn3AM@<{RcYgW`O?Wd)9T&c`_AxhVK&5M9xDotd8MUKjKjj|KEt z_m;pho{o%DJUzib1H?mr0hh1y{-DRYj|Yx*pQ1R=+bqT@4+{-^mN7lmeGTJO_x0d| zb>9nmtosSjW1i1}9_Q^<;F#xoj8mSUf`10c^GBwqy4#jXejeH@PWhzwJ#qoZc+8Ab zJf*-Nw2^N7sSlb@YI7 z@{cp{e*=1qKb~sWQFk+L#F^eDKwu`asGD&AIzIO<22sBj8mL}jMI2S6qmoCex4few+7tCQ6y1pG(X8FGvk!EoWSM$ zp>?Sc<8*zMP+a=r{3#E5IZvqH%D|;RtxI(oC;uh}{w;tP7d{k!JMh8z*#)@lm)0du z#;M=_;E&@90=@L7>vsrnyzasoC;vzT|Cyl2_~$WB<6Q(kX2`>Grl;#=E#u^~iE$d& z4#ugDdli?*xGo)Ldg}KiaLmso#%W!;1^$@-7r?W?c;A8#=It}%G~TooL}RhhbwP1v zVw}dCO>uc_7C+>Zhv~_uFyo{zVZfaYcx?mT)PT1$;5`g@UjrU&z(+Dp`H3*#vkmwU z27EQ+l(!AQ<@}*_X(!`!eH~O>#)tFg80hWAIg0-*aOqF$(ly4(|E}WPKNfg#;Y0C1 z2OoREX`cKAT=q-r68(WaIX@+*er=t^f!KJz_KMSdrt3EsaOp#zUz-^x|56726+n;i zS7n^WTMK;5qF>?-nV#~{jB(PpVVuU*iE*l9cg5u~u1lUwPyO}-j`;~;oYtk`;E(ev z8aS>?KY$PBZ3W{r-ZkJOcZu%?y^PaU4fq)7@pb4m;26&z;DhlzVx0Po10T6d+~h0{ z#76Uz;>oPI3=iWe1RUdW03VE}9OKll_#>IxCjBvPaxwI zPYC#6JQF~V@yr4}#|;jFizuL2L3qSHK0fTjf~THw*$xV z?gxJy?{VNb-V4BSyw|}WQD7pAx`vyyX?=*H>lWINrL9(|DVJKaRH*=yALq7^gV90mt!rf=?!aT@Ph;5gpR;E&_o13V{;_b6~2?`g&P zcrOCS@!n>f#v2R%INs-=$MOEfIF0uca2#)1IY_bb`D_n7r#MeOd4c12&5HB!mSmiK z92uwQmnw{_+Y?hw#pSUX;%UJ2`t7DT@7IIr$;TJCtS`MD4`!U| zI}H4>zGFd;^^IVh#uWt|>l+RJa+mZ=fMb34f{%=UeLC?=Y$rgE_uJ=~{x_w+2Kut1 zJ@xw*^i>6?Jg1ijVw3Yn_IpS9O3b*8&~`9Q7*| zmvLghyA1TFK`(b{ytjbM@y4m~J_R2f?-$U^T^es88HCuR?|0&dxMXrmC4Mq%d-^Y1 zwJ*8scbEz&D{$JENd5O$nvc{^R(i8MDK_boUE9-tsjoX(_0yGJzNV9#)aTOn^j|W! za-(?WD}8;9>YQSb$OX8JXQ|S+0j~b58;x`ZF7?}$zBh37Uzlj5FL0?pr}P7WtN#)} zBVoX${;ATB2Cn`|w?-xbm--B8br1zy{gYgcL<5(4`n#%&ffrT#@?j-#sjsB`*8?x6 z_T|Gi;8I^l>GuIwUlrHLQQ%VVs`O`omr(oi;WBWk@2m8;fvc}%Y9to8)K60S7r@J? zefjVXxYTb`dTm09V>z$NDUE!vl|XDX-(r8`B0W|}6)Rg+KQoyCY zjk>O#fL8#0b>LDzTIuTpS8q{htz3Xh{amGQ16)1TYx>T>rGACd+iGX^HI-5(5v>(+ z?MW|wA|wA*Ox#qNyLcmf!AQa-~NZ>EkX zG48C6=P+JY#kquW7nPr%884&y-Nm?@I{uCE)5_-}#E}wjMMWL z{XJV6Z;;CKMy99!icy|~POcAsseYXpf2??2#y6_tE{uDqWBPk#6i*)&&rqh{ulQWX z->YM)j|@ZIT52tRVtQp`+M&4At6NU(6n(Fd;>oSX^^Ez{Q^#}zOnUnJyjj(HL%fIb zF*EM1cp1izsX*&6eoED;J>zsebYXmt()VKggW}$d=ThV9&$vbD2Qu!e^mN}%FNI~c+EJ?kJRd>f#Of4{IfG2 zt$0z!+pG9XDNgaMQm+r|F@312dw0g~D<2Q$Q?;U=h)|}#sr18`{)W2An#T0>_qAs; zeYlhEf0*fqt2j?E{R4HAc#G-Bsd(t`-BTW#shiMuOizD*{4?`EC|_iYt(Cf|qPn!x zv8lb{S?THTXj43m)wm8Y{XKQ#70dj; zQ}M(xeJ!OotD9-^&!Y4t6sP#NW!2+v!SoGuY--E&bLE>xVxzw+P5w1?Y&y*Jf%45f zu~k(!uB3l10}xwn#VHFKrB45lxk-XOcf^bWec=>gNb$^gXnp6Rcvc(e&3 z&Qm;BRDOr4b`<{wr5~+0=`X4}&SLsgN*~Si6SZheCi*+V+3e-be(Dw zN1UU0=z6EuU&LwMsISINoYtS-jMF+cnsHhW7c)-l>ORJ4eZI{&t@D&ziie&r%o4!3 z=y|F>bjTBXPa3x zms5$>Q*x`Xc8cSR7{S!EBbiCQCoI?B`c|Uvm^aV)pn_4LOVEMZJ$auu@V z`Y&}|Zy&AhUu6HXEw!iqdkL0Y|7RNO?fbIvQ+xfa_* zts=1#q}n5s`&@fiFnLSLhG_~@?Rotve(5E*o8m`$^7boL`_61(;O(!7w#n6RfVwdn zpp0exa*7{nPxVW#Zy^&OXlTDpi__|lxy6ILMd$4$V