Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 09:02 01 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : CMM2: Calculate factorial

Author Message
bar1010
Senior Member

Joined: 10/08/2020
Location: United States
Posts: 197
Posted: 09:55pm 25 May 2021
Copy link to clipboard 
Print this post

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: Australia
Posts: 6283
Posted: 01:24am 26 May 2021
Copy link to clipboard 
Print this post

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 States
Posts: 197
Posted: 03:29am 26 May 2021
Copy link to clipboard 
Print this post

  TassyJim said  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


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 States
Posts: 405
Posted: 04:14pm 26 May 2021
Copy link to clipboard 
Print this post

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 States
Posts: 442
Posted: 05:19pm 26 May 2021
Copy link to clipboard 
Print this post

  bar1010 said  
   if last >= limit then print "Overflow!")


Is the right parenthesis an error?
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4044
Posted: 09:23am 27 May 2021
Copy link to clipboard 
Print this post

Looks like it is.

John
 
vegipete

Guru

Joined: 29/01/2013
Location: Canada
Posts: 1132
Posted: 06:02pm 27 May 2021
Copy link to clipboard 
Print this post

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";
 print
end sub

Visit Vegipete's *Mite Library for cool programs.
 
Paul_L
Guru

Joined: 03/03/2016
Location: United States
Posts: 769
Posted: 07:31pm 27 May 2021
Copy link to clipboard 
Print this post

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 States
Posts: 197
Posted: 10:46pm 27 May 2021
Copy link to clipboard 
Print this post

  vegipete said  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";
 print
end sub


Nice.  Has anyone wrote a bignum program capable of adding, subtracting, multiplying, and dividing floats?
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025