using System;
class A
{
public static void Main(string[] argv)
{
DateTime t1 = DateTime.Now;
BigFact( int.Parse(argv[0]));
DateTime t2 = DateTime.Now;
TimeSpan ts = t2 - t1;
Console.WriteLine( "Run time {0} ms", ts.Milliseconds );
}
public static void BigFact( int n )
{
int length = (int) (Math.Log10( 2 * Math.PI ) / 2 + Math.Log10( n ) / 2
+ n * ( Math.Log10( n ) - Math.Log10( Math.E ) ) ) + 1;
Console.WriteLine( "Total Length:{0}", length );
int currentLength = 1;
int beginPoint = 0;
UInt64[] result = new ulong[ length ];
UInt64[] carry = new UInt64[ length ];
result[ 0 ] = 1;
const UInt64 BASE10 = 10000000000;
for( UInt64 i = 2; i <= (UInt64) n; i++ )
{
for( int j = beginPoint; j < currentLength; j++ )
{
result[ j ] = result[ j ] * i + carry[ j ];
carry[ j ] = 0;
if ( result[ j ] > BASE10 )
{
carry[ j + 1 ] = result[ j ] / BASE10;
result[ j ] = result[ j ] % BASE10;
if ( result[ j ] == 0 ) beginPoint++;
}
}
if ( carry[ currentLength ] > 0 )
{
result[ currentLength ] = carry[ currentLength ];
carry[ currentLength ] = 0;
currentLength++;
}
}
for( int i = currentLength - 1; i >= 0; i-- )
Console.Write( "{0} ", result[ i ] > 0? result[ i ].ToString() : "0000000000" );
Console.WriteLine();
}
}
第一题我用了分组的方法,10个整数存一组,末尾0不参加运算(也不完全). 100!用10ms, 1000!用20ms,10000!用433ms,100000!用 539 ms。 (IBM T40P, windows xp, .Net 1.1 )
贴出代码来抛砖引玉,看看谁还能写出更快的算法。