Article View: comp.lang.pascal.misc
Article #50Re: Tough FACTORIAL math problem...
From: Bruce Kaskel
Date: Sat, 17 Feb 1996 10:38
Date: Sat, 17 Feb 1996 10:38
72 lines
3012 bytes
3012 bytes
In article <4fr8be$ass@news.iconn.net>, The Crow <thecrow@iconn.net> wrote:
>Here is what I am trying to do, I want to find the last NON-ZERO digit of a
>given factorial. For instance,
>
>5! = 120
>
>so the last non-zero digit is 2. I want to be able to do this up to 1000.
>Problem is, no matter how huge of a data-type you use, there isn't any way for
>the computer to handle 1000!, it is however possible to find the last non-zero
>digit somehow. One thing I have tried is as I went through mulitplying the
>series of numbers in the factorial (5 * 4 * 3 * 2) I would remove all the
>trailing ZEROS, I got this to work up to 789, but it wont work with 1000 and i
>am not really sure why. If anyone has a clue how I can do this let me know.
>
>--
>The Crow - thecrow@iconn.net
>"It can't rain all the time"
>-Kryptology
>
One article in this thread was recently posted to sci.math where I responded.
I don't know why it didn't show up here, but here was my response.
I don't see this as a hard problem. Of course, you don't need to work
with n!. In fact, you only need to keep a few bytes of data.
=========================================================================
One can keep track of rightmost nonzero digit by storing two things:
A) the number of factors of 2 which have not been ``canceled'' by a 5.
*
B) The relavant unit in (Z/10Z) .
=========================================================================
Here is some simple code:
int foo(n)
int n; /* the input is n for n! */
{
int i,j,u=1,t=0;
for(i=1;i<=n;i++)
{
j=i;
while(!(j&1)) {j>>=1;t++;}
while(!(j%5)) {j/=5;t--;}
u=(u*(j%10))%10;
}
if(t) {t&=3;if(!t) t=4;} /* if t>0, only need t mod 4 */
for(i=0;i<t;i++) u=(u<<1)%10; /* include factors of 2 */
return(u); /* The rightmost non-zero digit of n! is u */
}
For very large n you might have to be more careful about overflow in t.
But you only really need to keep track of t mod 4 once t is positive (but
you need to be able to distinguish t=0 for when n<2 or take care of these
few cases separately).
It would seem that faster methods could be achieved by looping over
the primes p<n instead of all numbers <n. Indeed, primes congruent to
1 (mod 10) could be skipped altogether (this is 25% of primes). I'll
elaborate on this idea if someone wants to hear it.
One thing, I usually read sci.math and not these comp.* groups. So e-mail
any questions. Thanks.
--Bruce Kaskel
kaskel@math.berkeley.du
Technical Details
Message-ID:
<4g4b6b$mls@agate.berkeley.edu>Path:
arc1-ca.pugleaf.net!info.ucla.edu!agate!kaskelReferences:
<4fr8be$ass@news.iconn.net>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!info.ucla.edu!agate!kaskel From: kaskel@kirkuk.berkeley.edu (Bruce Kaskel) Newsgroups: comp.lang.pascal.misc,comp.lang.c++,comp.lang.c,comp.lang.pascal.borland Subject: Re: Tough FACTORIAL math problem... Date: 17 Feb 1996 10:38:03 GMT Organization: U.C. Berkeley Math. Department. Message-ID: <4g4b6b$mls@agate.berkeley.edu> References: <4fr8be$ass@news.iconn.net> NNTP-Posting-Host: kirkuk.berkeley.edu