昨晚NetOA小组里有同学问我如何计算exp(x),但不允许使用Math.E, Math.Pow()和Math.Exp().一开始我给弄糊涂了,一想,这不得先算e,然后再幂上去么?
e是可以这样算出来: lim(n→∞) (1+1/n)^n
但是要拿这个数来算幂的话,直接用乘法就只能算整数幂了...郁闷
同学提醒说可以用泰勒展式.
exp(x) = 1 + (x^1)/1! + (x^2)/2! + ... + (x^n)/n! + o(n)
这就对了,马上想清楚关系.n只要取个足够大的值就行,我一开始取了0x0FFFF,后来发觉太大了没必要,最后换到了1000(100的话却又不够大...还没充分收敛).
写出代码:
using System;
sealed class Program
{
private const int A_BIG_NUMBER = 1000;
static void Main( string[ ] args )
{
PromptForInput( );
double input = Convert.ToDouble( Console.ReadLine( ) );
Console.WriteLine( "exp( {0} ) = {1}",
input.ToString( ),
Exp( input ).ToString( ) );
// compare result with Math.Exp()
Console.WriteLine( "exp( {0} ) = {1}",
input.ToString( ),
Math.Exp( input ).ToString( ) );
}
// Calculates exp(pow) with Taylor's Series
static double Exp( double pow )
{
double step = 1.0;
double acc = 1.0; // accumulator
for ( int i = 1; i <= A_BIG_NUMBER; ++i )
{
step *= pow / i;
acc += step;
}
return acc;
}
private static void PromptForInput( )
{
Console.WriteLine( "Enter a floting-point number as the power of e:" );
}
}
呵呵,这也挺有趣的,虽然是个很直观很小的程序.后来我顺便拿这题问了一下NetOA小组里的另外两个成员,他们做出的解答让我又稍微多了分信心: 多培养一段时间他们肯定也能写出很好的代码的;他们只是以前没学扎实罢了.
==================================================
另外,得提醒自己的: System.Double的最小正值用System.Double.Epsilon常量.切记.