![]() |
Forum Index : Microcontroller and PC projects : CMM2: Calculate factorial
Author | Message | ||||
bar1010 Senior Member ![]() Joined: 10/08/2020 Location: United StatesPosts: 197 |
Calculate factorial results using arbitrary precision math (bignum math). The results contain more digits than usual with an integer datatype. 'Arbitray precision math: calculating factorials 'Idea is to perform calculations with more precision than is normal with integer and float datatypes option base 0 const limit = 65536 'maximum number of digits const tbase = 10 dim string tdigit$(9) = ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9") dim integer digit(limit) 'the big number dim integer carry, d 'assistants during multiplication dim integer last, i 'indices to the big number's digits const fl = 47 'target factorial to solve for i = 1 to limit digit(i) = 0 next i digit(1) = 1 'the big number starts with 1 last = 1 'it's highest-order digit is number 1 for n = 1 to fl carry = 0 for i = 1 to last 'step along every digit d = digit(i) * n + carry digit(i) = d mod tbase 'the low-order digit of the result carry = d \ tbase 'Note: MUST use \ for integer division, not /, the carry to the next digit next i do while carry > 0 'store the carry in the big number if last >= limit then print "Overflow!") inc last digit(last) = carry mod tbase carry = carry \ tbase loop for i = last to 1 step -1 print tdigit$(digit(i)); next i print " ="; n; "!" next n do : loop new calculate factorial.zip |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
It's about 30 times faster than the code I wrote for the original maximite in 2012 Back then we only have 32 bit floats, no integers and many commands like INC not available. https://www.thebackshed.com/forum/ViewTopic.php?TID=4653&PID=46596#46596#46590 Jim Edited 2021-05-26 11:29 by TassyJim VK7JH MMedit |
||||
bar1010 Senior Member ![]() Joined: 10/08/2020 Location: United StatesPosts: 197 |
Thanks for sharing that link. I will see if can use that code for calculating pi and e using bignum math showing the values with each iteration. |
||||
William Leue Guru ![]() Joined: 03/07/2020 Location: United StatesPosts: 405 |
Nice! Now if we could convince Geoff and Peter to include bignums as a base type in MMBasic..... Nah! -Bill |
||||
toml_12953 Guru ![]() Joined: 13/02/2015 Location: United StatesPosts: 442 |
Is the right parenthesis an error? |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4044 |
Looks like it is. John |
||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1132 |
Interesting fun. Here's my quickie take on many digit integer math. Setup to calculate Fibonacci numbers up to 102 digits, although changing 'bigsize' would allow many more digits. (Press a key for each new number.) Main difference from bar1010 is I'm storing 6 digits per array element. This ought to be changed to 8 digits for better storage - 8 digits to ensure no overflow if multiplication were to be implemented. Plus I was lazy and didn't code multiplication, or check for overflow. ' Many Digit Math for Integers - quick test by vegipete ' Digits are stored in arrays ' The following uses base 1,000,000: this way, 6 decimal digits are stored in each element ' ' to do: ' multiplication/division ' decide how to represent negative numbers bigsize = 16 ' (bigsize + 1) * 6 = number of digits dim a(bigsize) dim b(bigsize) dim c(bigsize) print "Fibonacci Numbers - each number is the sum of the previous 2. Fib0 = 0, Fib1 = 1." a(0) = 0 b(0) = 1 do PrintLong c() AddLong a(),b(),c() CopyLong b(),a() CopyLong c(),b() do : loop until inkey$ <> "" loop '======================================= sub AddLong x(),y(),z() local i,tmp,c=0 for i = 0 to bigsize tmp = c + x(i) + y(i) z(i) = tmp MOD 1000000 c = tmp \ 1000000 next i end sub sub MultLong x(),y(),z() ' exercise left to the reader end sub sub CopyLong x(),y() local i for i = 0 to bigsize y(i) = x(i) next i end sub sub PrintLong x() local i,lead=0 for i = bigsize to 0 step -1 if x(i) or lead then print right$(string$(lead,"0")+str$(x(i)),6); lead = 6 endif next i if not lead then print "0"; end sub Visit Vegipete's *Mite Library for cool programs. |
||||
Paul_L Guru ![]() Joined: 03/03/2016 Location: United StatesPosts: 769 |
If you take this a little bit further you wind up rewriting the BCD math routines that Wayne Ratliff incorporated in Vulcan > cBase > Clipper > FoxBase etc where numbers are treated as very long strings of characters and you use look up tables to multiply and manually carry remainders just like you would on paper. It would seem to be MUCH slower than doing it in binary but it really isn't because you don't have to convert back and forth between binary for calculation and decimal for input and display. COBOL, in its earliest incarnations, had BCD routines which it could call. Paul in NY |
||||
bar1010 Senior Member ![]() Joined: 10/08/2020 Location: United StatesPosts: 197 |
Nice. Has anyone wrote a bignum program capable of adding, subtracting, multiplying, and dividing floats? |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |