Calculating Huge Numbers

download Calculating Huge Numbers

of 8

Transcript of Calculating Huge Numbers

  • 8/12/2019 Calculating Huge Numbers

    1/8

    NeilJ u enkingy tilitiesDo you know the number of different waysa deck of cards can be shuffled? The an-swer-52 fac to r i a l - i s 80 ,658 ,175 ,170, 943, 878, 571, 660, 63 6, 856, 403,766. 975, 289, 505, 440, 883, 277, 824,000.000.000 000.ut don t exp ect to cal-culate this number using any ordinary PCprogram.Most programming languages supporttwo basic kinds of numeric variables: inte-ger and floating-point. The num ber of val-ues integer variables can represent is fixedby the num ber o f by t es u sed to s to rethem-generally 1 2, or 4 bytes. C alcula-tions using integer variables, while com-pletely accurate, are not suitable for ex-tremely large numbers.Floating-point variables can c over avastly larger range of numbers than inte-gers; however, these variables are limitedto a fixed number of significant digits.This means that any program that performsfloating-point calculations is subject toround-off error s. Such errors are cum ula-tive. so after a series of calculations it smore tha n likely that the result may be offby quite a wide margin.The HUGECALC utility presented inthis issue avoids the probleks associatedwith both integer and floating-point vari-able types by representing numbers asstrings of ASCII digits. It works with ex-tremely large numbers yet maintains com-plete accuracy.The key to HUGECA LC s operation isthe real iza t ion that g iven a suff ic ientamount of time, and paper, youcould evaluate an expression such as 2Im.That is to sa y, you have n o built-in limit onthe size of the numbers you can figurewith, and the manual techniques of multi-plication, addition, subtraction, and so onhave no intrinsic limits. By making thecomputer perform math in the same wayyou would, I ve vastly expanded the rangein which it can perform accurate calcula-tions with every digit significant.HUG ECAL C can generate results of upto 254 digits, and in theory its inputs canhave up to 253 digits. In practice, howev-e r , t he DOS command l i ne max imum

    HUGECALC HandlesHumongous NumbersEasily and Accurately

    length of 127 characters limits the inputlength.You can dow nload the executable andsource files from PC MagNet in one file(HC.ZIP) or as separate files (HC.EXE,HC.PAS, and CALC.PAS). Instructionsfor downloading appear on the PC MagN etNews page, which follows this article.You can use HUGECALC as is, or youmay wish to include its functions in yourown T urbo Pascal programs. In the lattercase, note that the Pascal source files re-quire Turbo Pascal 6.0 to compile. If yourcommunications setup is not equipped tohandle binary files, you should download

    HC .BAS instead. When you run this oncein BA SIC , it will create the executable filefor you. If you don t have a modem at all,you can get a copy of the source code bymail or fax. Simply send a postcard withyour name and address (or fax num ber ifapplicable) to the attention of KatherineWe st, U tilities, PC Magazine, One ParkAvenue, New York, NY 10016; no phonecalls, please.USING HUGEC LCHUG ECA LC is a command-line six-func-tion calculator: It performs the standardfour arithmetic functions (addition, sub-

    traction, multiplication, and division), towhich it adds exponentiation and factorialfunctions. The basic syntax for HUGE-CALC isHC n operator [n]

    where the values of n (the operands) con-sist of one or more digits. Note that thesyntax assumes you w ill name the execut-able HC , just as I have don e, to avoid typ-i ng o u t H U G E C A L C e v e r y t i m e . Y o ushould also note that no com mas o r otherformatting characters are permitted andthat the operands must be positive num-bers. Th e six recognized operators are + ,-, , and 1 together with for expon entia-tion and for factorial. All operators ex-c e p t f a c t o r ia l r e q u i r e t w o o p e r a n d s ,though (as discussed below) the first oper-and may come from DOS Standard Inputrather than the command line. In addition,there must be at least one spa ce separatingthe operator and each operand.The format in which H UGEC ALC pre-sents its results depends o n their destina-tion. If you simp ly ask the program t o dis-play its results on the scre en (the default) orif you redirect its output to a printer or an -other device. HUGE CALC first urints thename of the function and then prints thenumeric result with com mas inserted everythree digits. HUGEC ALC begins insertingthe commas at the end of the number andworks back toward the beginning. If in-serting another comma would make theoutput string longer than 255 characters,HUGECALC simply stops adding com-mas. For exam ple, in the following calcu-lation HUGECALC has no room for thelast two comm as.

    SEPTEMBER 24,1991 PC MAGAZINE

  • 8/12/2019 Calculating Huge Numbers

    2/8

    However, if you r d i t he output to afile or pipe it to another program, HUGE-CALC omits the function name and thecommas altogether. In this format the pro-gram output can serve as an input operandfor HUGECALC itself. This means thatyou can store partial results in a file andfeed them to HUGECALC later, using theredirection symbol

  • 8/12/2019 Calculating Huge Numbers

    3/8

    FUNCTION mnb(A, B r string) I string:V R T r string;psn, Lan Word;

    barrow, 1 ~HoolauniBEGINsub(#] r- n:IF (Lensahfa? 25+) TW.n Rit ;IF (ungthtal 1 5 1 ) TNEN Exit:IF A[#] = T m xit:IF B[0] - t 0 T U W Exit;barrow I* False;nlnus t- False;(subtract sm ll sr fm larger)IF COQpam(A, 8) -1 TUENBE5INminus i Trim:

    VAR TIBEGINdrvrf b n [IF AIF BIF CBB

    T : A:END: A i Bi B 2 T:IF Lengthfl) Uagtb(l)) TREN Ian suc c(~ ang *h( ~)~ELSE Len : su~(Mngth(B)):r- ImftPadE(A, Len);

    B : MftPadMfB, Len);~iLlchtr(~(1~.cn, 0 ) ;T[g] I chartun);pan t- succ(Len):{subtracl digits f r m rrght to left)WHILE pan > 1 OBEGINo.c(psn,:IF b r r w TEENTtPBnl i subChar(Prad~A~psn1).(pen1, borrowELSE Tlpmnl : eubChartR(pen1, B(p8nl. borrow);END;T r m M a d * T )IF T . Tn n T : '9';IF minus F R WBEGINrcove(T(l], T[Zl, length(T));Tfl] - - IInc(TI*l):END;sub r - 7:END?Puunxon prwl(?.. B t strxng) r str%w:vAR T1, T : string:pan , time. N I Word:BmZU

    =---.-.IF (LengthtA) ungth( B) 254) TnEn Exit IF A I M ] - te EN ~ x i t ;IF 8[8] - (9 THEN Exlt;(mltlp ly larger y smaller)BEGINTI A; A 8- B; l t= TI;4 ND i

    T2 i s '9';(for each digi t of mltip Ller, right to luft,add together an uppropraatm m nbs r of q i e oof multiplicuid, tack the right nraber ofreroe. on the end, and add the result to therunning total in TZ)F OR p m n : Langth(B) D m m 1BEGINtinmu r- ord(B[poon])-4srIF ti%+& 0 TEEN TI r - 0ELSBB M n NTI I A;

    FOR N : 2 to t h . D OTI 1- add(T1, A);

    -7FillChar(TI[oucc(leng*h(Tl))I,lmgth(8)-posn, *E');xno~Tl[sl, length(Bl-wsn);TZ r- add(T2. Tll;EieD;prod 1 T2;END;

    CPEN!:END:FUNETTCVAR T1.BEGINTI tT2 rIF ( PNHI

    I

    -r(VRR TI,BEGINFI? a[IF E lpowaxIF B9-1SF ET1 :.T2 tT3 c(=aleWHILlBE(414I

    FUNCTION divid.(A, B String; VAR I m r Strkaq):String;

    command line utility CED. CED lets youenter several commands on a single com-mand line, but by default it separates themwith a caret ^) . Thus, if you have CEDloaded, the command line

    will be interpreted as two distinct com-mands: HC 52 (which results in an error

    message) and 52 (which causes a Badcommand or filename message fromDOS). The solution is to change CED'schain character, at least temporarily. ThecommandCED CHAINCH

    will cause CED to use ASCII character28as its chain character, leaving the caret

    free for use by HUGECALC. (You could,of course, use another uncommon charac-ter to replace the CED chain character.)THECALC UNIT-HUGECALC S BRAINThe CALC.PAS unit listed in Figureconsists primarily of the operator functionsAdd, Sub. Prod, Divide, Fact, and Power.These work on numbers expressed s nu-meric strings. The most important func-

    SEPTEMBER 24,1991 PC MAGAZINE

  • 8/12/2019 Calculating Huge Numbers

    4/8

    BASM, TURBO PASCAL 6.0'5 BUILT-t- L c

    byMIJ.RubenkingRogrammen will b happy ta l mthat, beginning with Vctsion 6.0,Tur-bo Pascal has built a simple assemblerright into the hzcgmdDtvel-En-nt (IDEI. B A W handles all~8086machlnecadeinstruct iws ,rznbgiven the proper compile direc-t i v e s l t suppotts 8087,80286, and80287 operations as well. BASMdocan't p i d e he fuP scope ofastand-alonepssernMtr; it mostlyhandb onlyASM instructions, not directives likeDRO,STRUCT,orWU The datadir-cctives DB,DW,and D D (DefineBw,Define Word, and Define T)ou-bloword) are s~pported,though onlyfmpreinitializ4dvalues.To nse the TF 6.0 built-in BLssem-blar, you simply insert a block of as-sembly fnmctiom, into your program,precededby the new keyword Sndending with END. ZbE irrlmnrctiolls cannfertoPascal eonstants, variables, andproocliures By name. h's a v ia hpmvementover using MIME codeorexlemalaasembltrfiles.W M B WWhen you switch to BASM ham IN-LINE you no longer have to consult anassembler reference or shell out of theIDE and run DEBUG to figurcout thebytes for aparticularcombinationof as-sembly instructionsand aperands. slong as you know the name of the nstruction you want, you just type t in.In INLINE, by contrast, it'snotenoughtoknow thename, lxawe inwmbina-tlon witb different operands h e sameinshwtion is mpramted by differentbytes. Forenample,you have todlstin-p i s h among bytes used for movingdata intoa regis& when the sourcle isa. vatiable, a global variable, a em-atant, an argument b a j w x d u e drfunction.A second advantage is that BASMcompletdy eliminates the anercustasko t g offsetsf o r ~ i n s t n r c -t h s . WhenusingN Eyou'd prob-ablyAnd yourself cuuntiagaloud Ihexw b ointing atbyteson the xmn-

    I

    PC M A W I N E SEPTEMBER 24,1991

    And if you insett oran INLINEblock,thejumps again If achangetothe codcmbves a condhion l iump destinationbeYdtheranged-i28b127bytes,you have tomo e the jump, and th tchange means you have nxaIculatcalltheotherjumpsagainBASM handles thi messy pmcegainvisibly. Ynu simply Hlritcyour jumpirrstructioo nd o nt it at e label. If thelabel is too far away for a c o d i t i djump, BASMdoesn't flinch. Instead, ilgenerates two jump instluctions. lkiirst is a mnditionaljumpon p m s d ytheoppositeof theconditionyou speci-fied.hjumpsoverthenext imtmtionwhich is en ullconditsoaaljump to therequesteddestinationH'jrmweremit-ingW W ode,you'd havetodothisy d $ ith BASM you don't eventhinkabut itHavingthe asswnbletbuilt-ln isalsoan improvement over using ana m a lassembler. Each 11meyou make achangetaan external mutinc, youmustlearn the BE,assembb y w r modifiedASMprogram, reenterthe JDe. and e-com$le. TodebugexternalASM&,p u ave tousetb separate TurboDe-bugger. ut i you write y w r cadeBASM you can step W u g h it line bylinein dreID while watching the reg-istersin a Registerswindow. You csneven set conditimal breakpoints on thevalue:of theCPU registersAW P R OC E mE S A W ) FUNCTlONsIfs procedure or fngction containsn but ASM , you can in-cre se ts efficiency by q q m h g theAssembler directive to tsheader. Socha routinecan no IwgerhaveaBEGIN.,it begins with th heM keyword.TheCompiler perfom wme special optimiz tim onsuch outin=Itdoes notgem tecode to make 10cal copies o f value parameters thataren't 1,2, or4byW insize.

    Exoept far string functions, it duesnot &fme a function m a l t variable.

    aeia;rmaybereduoedmdoshirrim$$~ ~ r ~ Y r h e . e n d .with sreryti@ng supem-$stripped away', thesemtines c n befastWENTOUSEPAsMWhellntrbohp~indicatesthaxicertain mtina'isa b0ttIeneCk.hyoupmpm,thefkstthingtodoisempidw#whetktthe argoritbm itself i s emdentaspossibfe.If y o u h c;odi&nt.~this thwfwmaywmtto=*thealgorithmtp6ASM to speed itupI h a h t ~ ~ t o d o i s e x a m b ~ &fieddet w d c : g e d@'tba,'slpaw. ou CPII IRe l&M meb l y w i n ~ o w h ' I ' u r b d m m o r ~Vicw /CFUwid w inTu&&dw~pl%rf m t h i s . T A e h m y b e ; ~ u $ i e f i r ls kdtg iveg ypudreoptionddumpiQthedisassembbto a log file.When a qemkgiy simple line olP a d auses +ne orX.l.Kmcalls.to,lxjpl,tines in the rlmtime libnay, ~'L#'Prgood sign thatiyoum y be at& himp v e on it lnd if rseritsofJbcal i n e s ~ a v a o i g b l e b b ~ ~ i o t ct h e C P U r e g i d x s ~ a n d ~ , ~canpxobabbW vb tiryBASMcodetokeeptth~lrrcggsbw.Don't use $ASM .nibyou candcwhatyou nedtojustasvkll bP8c calme DDS Unit is laded with built.mutinesthal~Yeditbota CeSgtOrnfu n c t io a s ,a n d ~c a n &B imp k fcallsto almost.any st 0IWfudm with the MSDW and INTI4pltmdms.Frordireot-Zaaajarea of conveational RAM, ,pw thcME;M aadMMWarraq%,b r d d m rvariableABSOLUlE at the d e k lbd o n . And to read and mite4fieUGp0rtg,usctheSDRTandPORTWwrays. If you don't need BMM, W Iuse it. After @, plain Pascal code hv d ymIertoreadmlch- a

  • 8/12/2019 Calculating Huge Numbers

    5/8

    tilities

    t ions in CA LC .PAS , however, are thesimple AddChar and SubChar routines,which add an d subtract single digits repre-sented by ASCII characters. All of thestring routines in the CAL C unit depend onthese two s im p le func t ions , and s incethey're going to be called a lot, for the sakeof speed I wrote them as assembly lan-guage functions. The sidebar BASM ,Turbo Pascal 6.0's Built-in Assembler,explains how they are integrated into themain program.Besides taking into account that the val-ue of an ASC II digit is 30h greater than thenumber it represents, there's n othing reallyunusual about the AddChar and SubCharfunctions. SubChar begins by movingFAL SE into the borrow parameter. It takesthe difference of the two arguments andnotes whether the result is less than 0. Ifso , it adds 10 to the result and sets the bor-row parameter to TRUE. Finally, it adds30h to the result to convert it back to anASCII numeric character.AddChar is very similar. After addingthe two digits, AddChar subtracts 60hfrom the total; that's qu icker than subtract-ing 30h from each parameter individually.It then checks whether the result was great-er than 10. If s o, it sets the carry parameterand su btracts 10 from the resu lt. Finally itadds 30h to the result to convert it back intoan ASCII digit.

    DDING NUMERIC STRINGSYou learned as a child that you can add twolarge numbers sim ply by adding the digitsfrom right to left and carrying a 1 to thenext place if the sum exceed ed 9 And youlearned to subtract one digit at a time, bo r-rowing from the next place if the subtrac-tion would result in a negative number.The Add function adds two numericstrings together in exactly the way youwould add them on paper. First of all, theAdd function sets its result to an emptystring, which is the signal for an error. Ifone of the input strings is emp ty or longerthan 253 characters, the Add functionexits, leaving its result set to the emptystring.If the input strings are valid, Add left-pads each with zeros to one more than thelength of the longer one and creates a resultstring of the same length, also filled with

    zeros. It then steps through the stringsfrom the last character to the first, adding

    the digits from the two input strings andstoring the result ing digit in the resultstring. At each step of this process, ifthere 's a carry pending, it adds to thenext digit to the left.After processing the input strings, theAdd fun ction check s to see if the very lastaddition produced a ca ny . If so, it sets thefirst digit of the result string to I Then ittrims leading 0s. If the result of the trimfunction is the empty string, it replaces itwith the string 'O', since that is used to sig-nal an error .

    SUBTR CTING NUMERIC STRINGSSubtracting numeric strings takes only alittle more effort than adding them. If thesecond parameter is greater than the first,the variable minus is set to TR UE and thetwo parameters are swapped. T his way thesmaller number is always subtracted fromthe larger. Note that a special function isneeded to determine which of two numericstrings is larger; if you simply used thebuilt-in > and < operators straightaway,you'd find that '4' is greater than '100'.After leading zeros are removed, if thestrings are of different lengths, the longeris the larger. If they're the same length,then they can be compared using TurboPascal's > and < operators. The Compa refunction implements this simple algo-rithm, returning -1 if its first paramete r isless than the seco nd, 1 if the first parameteris greater, and 0 if they're e qual.As with the Add function, Su b fust setsits function result to the empty string andexits if either of the input strings is invalid .If both are valid, they're checked to de-termine which is larger and, if necessary,they are swapp ed. Then the smaller is sub-

    tracted from the larger, from right to left,one character at a time, borrowing as nec-essary. If the minus variable is TRUE, aminus sign is inserted at the beginning ofthe result.MULTIPLYING NUMERIC STRINGS

    When you multiply two strings on paperyou write the smaller below the larger andmultiply the larger by eac h individual digitof the sma ller. You write each partial prod-uct below the previous on e, offsetting it tothe left by one more decimal place. Final-ly, yo u add all of the partial products to getthe resul t. Th at ' s exact ly how HUG E-CA LC multiplies numeric strings.If the sum of the lengths of the twoopera nds, A and B, is greater than 254, theresult will be too large to represent as a nu-meric string, so rod (the multiply func-tion) exits with the result set to the emptystring. It does the sam e if eithe r operand isempty. Then Prod checks which operandis larger and, if necessary, swaps them tomake B the smaller of the two.The variable T 1 holds the partial prod-uct for each digit, and T2 maintains a run-ning total of all the partial products. T2 isinitialized to '0'. Prod then steps throughthe characters of operand B one at a time,from right to left. If the current digit is '0' itsimply sets the partial product T1 to '0'.Otherwise, T1 is set to the value of oper-and A, which is repeatedly added to itselfto get the desired multiple. Zeros are ap-pended to the result to produce the equiva-lent of w riting the partial product offset tothe left. Then T is added to the running to-tal in T2 . Whe n A has been thus multipliedby each of the digits in B , T2 ho lds the re-sult, so the last step is simply to return thevalue of T2 .DIVIDING NUMERIC STRINGSWhen it com es to division, the easy analo-gy with pencil-and-paper math breaksdown . As mu l t i p l i ca t i on was accom-plished by repeated addition, so divisionmust be done by repeated subtraction. Af-ter the initial check for valid parameters,the Divide function sets up three tempo-rary variables. T 1 initially gets the value ofthe divisor (parameter B). T2 is set toand T3 to '0 '. Then zeros are appended toboth T1 and T 2 until T1 is not less than thedividend (parameter A). As a result, T1now contains the divisor times some pow-er of 10, and T2 contains that power of 10.The result will be accumulated in variableT3. Now Divide is ready to perform som erepeated subtraction.

    SEPTEMBER 24 1991 P M G ZINE

  • 8/12/2019 Calculating Huge Numbers

    6/8

    and T2. Hence T1 is always equal to T2 NUMERIC STRING FACTORIALStimes the divisor B. The inn er loop keeps With the four basic functions in place, cal-subtractingT1 from the dividend A until A culating factorials by repeated multiplica-is less than T I , and each time throug h this tion is a snap. Note, howe ver, that the FactRemember that TI started off with the loop T2 is added to the accumulator T3. function must be nonrecursive. A recur-same value as the divisor-but with a After all possible subtractions, the quotient sive string-based factorial function wouldnumber of added zeros. The main loop is in T3 and the remainder is what's left of use a minimum of 5 2 bytes of stack forcontinues while T1 is not equal to the divi- A. You'll want to trace through this proce- each level of recursion. You can calculatesor; each time through the loop, the last dure a few times, however, to assure your- the factorial of numbers as high as 44zero is chopped from the end of both TI self that it really does perform division without overrunning the length of a numer-

    ($A+,B-,D-.E-,P+,G-,I+,L-,N-,R-,S-,V-,X-) Exlt;( n 16384.8,P) END ;PRUZRM Bu(J.C~E: END:USES c.1c; Octrarue I- TULtEiCONST copyright 1 etrIng(8l) IIM.CALC I .@, W r i g h t I991 by + m :'Neil J. Ilubonking'l13111'~: nogarin. '1254' 1.i1 J. Rubonking';

    ASB tPb.tf. 3))II(IV All, 46h tocn function) mtr*lgo.nl.IWV AL W h (get dovie0 info subfunction) ~fauec(poon)~.LES DI, I -c(ly(ltfl(W*j+=n)tiIWV ex, E S : ~ I ~ m z m n l : , ,INT Zlh ~ n c ~ m t e ~ ~ rBOV N d Q urn:JC @end Addcomas s t miTEST DK $Qh (chock im- +lee bit) RJD;JZ @and (if NOT smt, juat mnd) END;IUC AL (return value is wv s )@end EeIliIF G0 tPU . p . lggB1KiINVAR ap, opluad. ruult, ram a atrillgi CASE ~ r t i ?opr at on Char; + , BtDrnIT mBwio.(OIitpIK.) TRE*m T QRPU.1(1 I 1100h4~: w i t * sun: ) I{ PURPWE : I U ~ I U ~ Urue if pasuot*ra UB nmult I- addcop, opRend)%corractly prrrr on the clnarnd lino -- and rr X.WViae(output) TREWaasipnn thorn to tho connct variabln if 80. writeLn(Mdcomm(rs.ult))v*a s : strinq(l]t 35SE writoLn(Re~u1t);8 : BytmiaraXN I- : BEGINI? ISb.Vlo+(~tplt) TKBNb i t s ( ' D ~ ~ C X r ) iroault sub ~op , PIIUI~))IT IaDovia.~.(output)NrltaLn(Addcotans(r..ult))35SE WritaLn(Resu1t);m D ;f I l E G mrr ~ o w v i o ~ ( ~ u t p ~ t )lWrit*(' PBODDCTl ) ;moult 1- prod(op, man$);IF ~ e ~ e v i ~ e q ~ t p u t )RR~WriteLn(JIddComa(n8ult) )Exit: ELSE nitoLn(nemu1 t)r: m ;IP 8 op t- P U ~ ( l ) l I BEGINIr I*D.vic.(outpUt) THENbit.(' Q w m I E m l );result a divide(op, opmnd, r m # ;If I~Davice(0utput) HENBEGINWr ite L no*fdC omM (r . .u l t ) ) ;

    Write('wu1NDERr ) ;WriteLn(MdComna(r~)):.)IDsLsE uriteLn(R..Ult)l;1 BEGINIT x#ovi ce{output) ~ W NWrite(' FACTORIAL ,):reoult r- tmt(op);1r I.mviC.(Output) rnb l t . L l r ( M d c ~ ( n ~ ~ t j ) .ELSE WriteLn(Reau1t):' ' : BEGINIr Ismviar(outpUt) n W NNritoLntCopyriqh~ t write(' P ~ I ) ;WritoLn('*',aprmd," iw ot a positive int.ger.'): msult r- panrlop. oprandl;Exit; Ir I.WViCe(Output) TmmSnDi Rlt.i.a(MdCaraau(mmltj)Qm ELSE WrlteLn(Resu1t);

    -1;SWD:ewD.

    Figure2: The HUGECALCprogram ets you perform math operations involving huge numbers while retaining complete accuracy.PC MAGAZINE SEPTEMBER 24 1991

  • 8/12/2019 Calculating Huge Numbers

    7/8

    tilities

    I HUGECALC8 8 1I EM CommandI

    II Neil Rubenking September 24, 99 Utilities)I A command line calculator that can perform addit ion,I Purpose subtraction, multiplication, division, exponentiation,I and factorial functions on numbers with up to 254I significant digits.II Format HC n operator ]I Remarks The operand variables can consist of any string ofI digits up to the 127-character maximum of the DOScommand line. The operands must not includeI commas or other formatting punctuation and must beI separated from the command and the operator by at .I least one space. Two operands are required for alloperations except factorial. The operators recognizedII are +, -, , /, ",and .I When output to the screen the default) or redirectedto a printer or other DOS device, HUGECALC printsI the name of the function and inserts commas at everyI three digits in the numeric result. If the output isI redirected to a file or piped to a program input,I however, only the numeric result is sent. Note thatwhen it accepts input from a file or via a pipe,II HUGECALC uses that input as its first operand.I Example f a program that prints 10,000 permutations persecond is asked to print all possible combinations ofII 13 characters, how long will it take? The commandI HC 13 I HC / 1 I HC / 36 HC /

    4II pipes the factorial of 13 the possible combinations) toI a second instance of HC, which divides it by 10,000I the permutat ions per second). The result is piped to athird instance of HC, which divides it by 3,600 theI seconds in an hour), and finally to a fourth instance ofI HC, which divides it by 24 the hours in a day). TheI answer printed on the screen isI QUOTIENT: 7I REMAINDER: 4I that is, 7 days, hours.II Note that all such chained calculations must bestrictly sequential and that parenthetical expressions

    are not supported.IIL - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    SEPTEMBER 24 1991 PC MAGAZINE

  • 8/12/2019 Calculating Huge Numbers

    8/8

    tilities

    ic string, but with recursion it would re-quire an impossible 72K of stack.The Fact function uses T2 as a counterand TI as an accumulator and starts by set-ting both to ' . If the input value is 0 or1', it's done . If not , Fact loops repeatedly.adding 1 to the counter and multiplying theaccumulator by the current value of thecounter. Then all you have to do is returnthe final value of the accum ulator.

    NUMERICSTRING EXPONENTI TIONThe most common way of calculating apower in Turbo Pascal is to use the Expand Ln functions: Y = xp i"Ln )How ever, these functions aren't availablefor numeric strings. You could performexponentiation by repea ted multiplication.but that method is potentially very slow.Fortunately, there 's a clever techniquecalled "halving and squaring" that per-fectly suits the Pow er function.Her e's how it works. Fir st, if the base is0, you return 0. If the exponent is 0. youreturn 1. Otherwise. you set T I to the base,T2 to the exponent, and T3 . the accumula-tor, to '1'. Then you begin halving andsquaring. Each time through the loop youhalve T2 , the exponent. If the remainder isI, you multiply the accumulator by thecurrent value of T I. Then you square T I .This process continues until T2 reaches0 , at which point T 3 contains the desiredpower.W hy does this work'?Try applying it toB", where B is any base value. First,translate the exponen t into the sum of pow -e rs o f 2 ; th at is , B ' ~ + ~ + ' ) .OUcan nowconvert that to BX *B4 *B'and still have anexpression with the same value as BI3.Keeping that in mind. apply the halvingand squaring algori thm. The first t imethrough the loop, you halve T2, making it'6' with a remainder of 1 . Since there wasa remainder, you multiply the accumulatorby T I , wh ich con ta in s B . Th i s co r re -sponds to the B ' factor in the result. Thenyou square T 1The second t ime th rough the l oop ,halving T2 yields '3' with no remainder.You don't change the accumulator, butwhen T 1 gets squared again it now has thevalue B4. The third time , halving T2 yields' 1 with a remainder of 1, so you mu ltiplythe accumulator by TI (whose current val-ue is B4) and squ are TI again . On the finalpass, halving T2 leaves 0 with a remain-

    der of 1. T I now contains B8,and you sim-ply multiply the accumulator by that quan -tity. T 2 has been reduced to O , so the loopends, and it's clear that you have the cor-rect result.If you were to perform exponentiationby repeated multiplication, the number ofmultiplications would be directly propor-tional to the desired power. Double thepower, and you double the number of mul-tiplications required. With the halving andsquaring method, the number of multipii-cations is proportional to the base 2 loga-rithm of the desired power. Doubling thepowerjust adds one more set of multiplica-tions

    M SSIVEM TH WITH HUGEC LCThe HUGECALC program itself is listedin Figure 2. Its task is to take a requestedcalculation such as 1000000 / or 5on the comm and line and return the result,using the functions in the CALC unit. Al-most all of the program is devoted to vali-dating input and handling output. The nu-m e r i c p a r a m e t e r s m u s t b e p o s i t i v eintegers, and the op erator has to be + ,-, *.I ,or .All operators except require twooperands. The GotParams function han-dles validating the parameters. If it detectsthat input is redirected and that input isavailable, it reads its first parameter fromDOS Standard Input.Assuming the GotParams function re-ceives a valid set of parameters, HUGE-CA LC performs the requested calculation.If output is redirected, it sends the resultingnumeric string to DOS Standard Output.For screen output, it pretties up the stringby inserting commas every three places.Function AddCom ma uses the Move pro-

    cedure to insert the commas rather thanTurbo Pascal's slower Insert procedure.HUG ECA LC uses the Assembler func-tion IsDevice to detect redirection of inputor output. This function calls the DOSIOCTL routine for information about thefile variable you pass to it and returnsTRUE only if the file variable actually re-fers to a device. IsDevice returns TRUEfor the built-in variable Output when it isnot redirected or w hen it is redirected to ad e v i c e s u c h a s th e p r i n t e r . I t r e t u r n sFALSE if Output is redirected to a file orpiped to another program. The s ame holdsfor the built-in variable Input: IsDevice re-turns FALSE if Input is redirected from afile or piped f rom another program.Note that when its output is not redirect-ed, HUGECALC prints the name of thefunction (for example, SUM ) before it per-fo rms the ca l cu l a t i on . Tha t ' s becausesome of the tasks you can assign to the pro-gram take an appreciable amount of time.Even on a fast 386 machine, calculating100 factorial takes several seconds, and onan original IBM PC it takes almost half aminute. By putting up the function nameright away, HUGECALC lets you knowthat something is happeningEXTENDING HUGEC LC FUNCTIONSIf you wish to exercise your programmingskills, there are severa l directions in whichyou cou ld ex t end the func t ions i n t heCA LC unit. For one thing, there's no needto limit yourself to 254 digits. Withoutmuch trouble, you could switch to usinglarger arrays of characters. For another,the existing functions wo rk only w ith posi-tive numbers . W ith a little wor k, you couldarrange to handle negative numbers. Forexample, you might modify the additionfunction to detect negative numbers andcall the subtraction function instead. Themultiplication function could note and re-move the minus signs from its inputs andput a minus sign in front of its output if ex-actly one of the inputs was negative.You could also expand your range bypacking the digits two-to-a-byte in a BCD(binary-coded decimal) scheme. And ifyou're more ambitious, try adding float-ing-point support. Once you understandthat you can represent numbers as stringsof digits, you're not limited to the numericdata types provided by Turbo Pascal or anyother language.Neil J Rubenking is technical ed itor of PCMagazine and author of PC Magazine'sTurbo Pascal Techniques and Utilities.

    PC MAGAZINE SEPTEMBER 24,1991