如何使用C#计算PI的值?
我认为可以通过递归函数实现,如果是这样,它会是什么样子,有哪些数学方程支持它?
我对性能并不太挑剔,主要是从学习的角度考虑如何去做。
如果你想要递归:
PI = 2 * (1 + 1/3 * (1 + 2/5 * (1 + 3/7 * (...))))
在进行一些修改后,这将变成:
PI = 2 * F(1);
使用 F(i) 的语法:
double F (int i) {
return 1 + i / (2.0 * i + 1) * F(i + 1);
}
艾萨克·牛顿(你可能以前听说过他;))想出了这个技巧。请注意,为了保持简单,我省略了结束条件。在现实生活中,你有点需要一个。
使用以下方式如何:
double pi = Math.PI;
如果您想要比这更好的精度,您需要使用算法系统和 Decimal 类型。
Math.PI
是一个常量。 - Willem van Ketwichstatic decimal ParallelPartitionerPi(int steps)
{
decimal sum = 0.0;
decimal step = 1.0 / (decimal)steps;
object obj = new object();
Parallel.ForEach(
Partitioner.Create(0, steps),
() => 0.0,
(range, state, partial) =>
{
for (int i = range.Item1; i < range.Item2; i++)
{
decimal x = (i - 0.5) * step;
partial += 4.0 / (1.0 + x * x);
}
return partial;
},
partial => { lock (obj) sum += partial; });
return step * sum;
}
不同算法的良好概述:
我对第一个链接中声称的高斯-勒让德-萨拉明算法复杂度并不确定(我认为是O(N log ^ 2(N)log(log(N))))。
但是,我鼓励您尝试一下,因为收敛速度非常快。
此外,我不确定为什么要将一个相当简单的过程性算法转换为递归算法?
请注意,如果您关心性能,则在有限精度下工作(通常需要“double”,“float”等输出)并没有太多意义,因为在这种情况下,显而易见的答案就是硬编码值。
using System;
namespace Strings
{
class Program
{
static void Main(string[] args)
{
/* decimal pie = 1;
decimal e = -1;
*/
var stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start(); //added this nice stopwatch start routine
//leibniz formula in C# - code written completely by Todd Mandell 2014
/*
for (decimal f = (e += 2); f < 1000001; f++)
{
e += 2;
pie -= 1 / e;
e += 2;
pie += 1 / e;
Console.WriteLine(pie * 4);
}
decimal finalDisplayString = (pie * 4);
Console.WriteLine("pie = {0}", finalDisplayString);
Console.WriteLine("Accuracy resulting from approximately {0} steps", e/4);
*/
// Nilakantha formula - code written completely by Todd Mandell 2014
// π = 3 + 4/(2*3*4) - 4/(4*5*6) + 4/(6*7*8) - 4/(8*9*10) + 4/(10*11*12) - (4/(12*13*14) etc
decimal pie = 0;
decimal a = 2;
decimal b = 3;
decimal c = 4;
decimal e = 1;
for (decimal f = (e += 1); f < 100000; f++)
// Increase f where "f < 100000" to increase number of steps
{
pie += 4 / (a * b * c);
a += 2;
b += 2;
c += 2;
pie -= 4 / (a * b * c);
a += 2;
b += 2;
c += 2;
e += 1;
}
decimal finalDisplayString = (pie + 3);
Console.WriteLine("pie = {0}", finalDisplayString);
Console.WriteLine("Accuracy resulting from {0} steps", e);
stopwatch.Stop();
TimeSpan ts = stopwatch.Elapsed;
Console.WriteLine("Calc Time {0}", ts);
Console.ReadLine();
}
}
}
public static string PiNumberFinder(int digitNumber)
{
string piNumber = "3,";
int dividedBy = 11080585;
int divisor = 78256779;
int result;
for (int i = 0; i < digitNumber; i++)
{
if (dividedBy < divisor)
dividedBy *= 10;
result = dividedBy / divisor;
string resultString = result.ToString();
piNumber += resultString;
dividedBy = dividedBy - divisor * result;
}
return piNumber;
}
计算方式如下:
x = 1 - 1/3 + 1/5 - 1/7 + 1/9 (... etc as far as possible.)
PI = x * 4
你得到了派!!!
这是我知道的最简单的方法。
派的值会慢慢收敛于实际的派值(3.141592165......)。如果迭代次数越多,结果越精确。
pie(0,1) = 4/1
pie(0,2) = 4/1 - 4/3
pie(0,3) = 4/1 - 4/3 + 4/5
pie(0,4) = 4/1 - 4/3 + 4/5 - 4/7
... and so on
因此,您第一次探索递归的机会是将“水平”计算编码为“宽度”参数增加(对于零高度)。
然后使用以下公式添加第二个维度:
pie(h, w) = (pie(h-1,w) + pie(h-1,w+1)) / 2
当然,这个算法仅适用于大于零的h值。
这个算法的好处是你可以很容易地用电子表格模拟它,通过逐步增加参数来检查代码并探索结果。当你计算pie(10,10)时,你将得到一个足够好的近似pi值,适用于大多数工程目的。