Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将PI定义为小数点后36位 < C++ >可以做到这一点: ifndef M_PI define M_PI 3.141592653589793238462643383279502884 endif_C#_.net_Decimal_Pi_Cmath - Fatal编程技术网

C# 将PI定义为小数点后36位 < C++ >可以做到这一点: ifndef M_PI define M_PI 3.141592653589793238462643383279502884 endif

C# 将PI定义为小数点后36位 < C++ >可以做到这一点: ifndef M_PI define M_PI 3.141592653589793238462643383279502884 endif,c#,.net,decimal,pi,cmath,C#,.net,Decimal,Pi,Cmath,然而,在C#中,我试图声明一个双变量,并用36位小数为其赋值。 这不起作用,因为双精度存储最多16位小数(MSDN docx)。我尝试创建一个隐式类型的局部变量,但编译器只是将其声明为double,我又回到了square one。也许我可以在C#中包含cmath 如何将圆周率定义为C#中的36个小数点?据我所知,C#在十进制中的精度最高,但它最多只有28-29个有效十进制数字。我认为,如果不使用自定义库,C中最多可以包含36位小数。如果你真的需要这么高的精度,你可以使用任意精度的C库,比如或。因

然而,在C#中,我试图声明一个双变量,并用36位小数为其赋值。 这不起作用,因为双精度存储最多16位小数(MSDN docx)。我尝试创建一个隐式类型的局部变量,但编译器只是将其声明为double,我又回到了square one。也许我可以在C#中包含
cmath


如何将圆周率定义为C#

中的36个小数点?据我所知,C#在
十进制中的精度最高,但它最多只有28-29个有效十进制数字。我认为,如果不使用自定义库,C中最多可以包含36位小数。

如果你真的需要这么高的精度,你可以使用任意精度的C库,比如或。因为它们是C库,所以您需要使用它们。。。但这将限制高精度pi的使用,仅限于使用您选择的软件包…

,您可以将其缩小到36位

这里是一个示例代码,我建议阅读全文及其背后的逻辑

public static HighPrecision GetPi(int digits)
{
    HighPrecision.Precision = digits;
    HighPrecision first = 4 * Atan(5);
    HighPrecision second = Atan(239);
    return 4 * (first - second);
}

如果你只想存储PI(不计算它),你可以拷贝值并将其存储在高精度变量.< /P> < P>你可以在C++中做什么,而在C语言中不能做的是为一个文字创建别名。C++编写的代码< >代码定义MYPI 3.1415926535897326846264338 327 95028 84/CODE >不将代码>π/C> >定义为36个位置。它只是给文字加上了别名

#define M_PI 3.141592653589793238462643383279502884
double pi = M_PI;   
这和写作完全一样

double pi = 3.141592653589793238462643383279502884;

这在C++和C语言中都是非常一致的。在C++中,值将与C语言中的精度相同,因为文字将被解释为<代码>双< /代码>,我相信两者都是相同的。

之所以将
M_PI
最多声明为36位,是因为这是
四位双精度
的最大精度。遗憾的是,没有C类中具有这种精度的本机类型。在C++中,没有从“代码> MyPI/<代码>中得到任何特殊的东西,除非您将其用作<代码> Quad双< /C> > < < 使用别名文字没有多大帮助,它只允许写入:

    float pif = M_PI;
    int pii = M_PI;
    double pid = M_PI;
    quad double piq = M_PI;

不幸的是,您需要使用自定义类型。

我发现这个问题非常有趣,所以这里是我的2美分

我采用了Machin公式,并将其应用于大整数的实现中(大整数具有优化的乘法和除法运算符)

最后,我将结果与测试结果进行了比较

在这里,2500个小数在i7 920@2.66 Ghz上以138毫秒计算

static void Main(string[] args)
{
    String referencePi = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275900994657640789512694683983525957098258226205224894077267194782684826014769909026401363944374553050682034962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382686838689427741559918559252459539594310499725246808459872736446958486538367362226260991246080512438843904512441365497627807977156914359977001296160894416948685558484063534220722258284886481584560285060168427394522674676788952521385225499546667278239864565961163548862305774564980355936345681743241125";
    Stopwatch watch = new Stopwatch();
    watch.Restart();
    DecimalX calculatedPi = PiHelper.Calculate(2500);
    watch.Stop();
    Console.WriteLine("Pi with 2500 decimals in " + watch.ElapsedMilliseconds + " ms");
    String hmmmmm = calculatedPi.ToString();
    if (hmmmmm == referencePi)
        Console.WriteLine("Pi approximation found");
}

public class DecimalX
{
    /// Integer represatation of the decimal
    private readonly IntX _integerPart;
    /// Power of 10 (10^X)
    private readonly uint _scale;
    public DecimalX(IntX integerPart, uint scale)
    {
        _integerPart = integerPart;
        _scale = scale;
    }
    public override string ToString()
    {
        IntX afterPoint = null;
        IntX beforePoint = IntX.DivideModulo(_integerPart, IntX.Pow(10, _scale, MultiplyMode.AutoFht), out afterPoint, DivideMode.AutoNewton);
        return beforePoint.ToString() + "." + afterPoint.ToString();
    }
}

public class PiHelper
{
    public static IntX InverseTan(int denominator, int numberOfDigitsRequired)
    {
        int demonimatorSquared = denominator * denominator;
        int degreeNeeded = GetDegreeOfPrecisionNeeded(demonimatorSquared, numberOfDigitsRequired);
        IntX tenToNumberPowerOfDigitsRequired = IntX.Pow(10, (uint)numberOfDigitsRequired, MultiplyMode.AutoFht);
        IntX s = IntX.Divide(tenToNumberPowerOfDigitsRequired, new IntX(2 * degreeNeeded + 1), DivideMode.AutoNewton); // s = (10^N)/c
        int c = 2 * degreeNeeded + 1;
        for (int i = 0; i < degreeNeeded; i++)
        {
            c = c - 2;
            var temp1 = IntX.Divide(tenToNumberPowerOfDigitsRequired, new IntX(c), DivideMode.AutoNewton);
            var temp2 = IntX.Divide(s, new IntX(demonimatorSquared), DivideMode.AutoNewton);
            s = temp1 - temp2;
        }
        return IntX.Divide(s, new IntX(denominator), DivideMode.AutoNewton);
    }

    private static int GetDegreeOfPrecisionNeeded(int demonimatorSquared, int numberOfDigitsRequired)
    {
        int degreeNeeded = 0;
        while ((Math.Log(2 * degreeNeeded + 3) + (degreeNeeded + 1) * Math.Log10(demonimatorSquared)) <= numberOfDigitsRequired * Math.Log(10))
            degreeNeeded++;
        return degreeNeeded;
    }

    public static DecimalX Calculate(int numberOfDigitsRequired)
    {
        int max = numberOfDigitsRequired + 8; //  To be safe, compute 8 extra digits, to be dropped at end. The 8 is arbitrary
        var a = IntX.Multiply(InverseTan(5, max), new IntX(16), MultiplyMode.AutoFht); //16 x arctan(1/5)
        var b = IntX.Multiply(InverseTan(239, max), new IntX(4), MultiplyMode.AutoFht); //4 x arctan(1/239)
        return new DecimalX(IntX.Divide(a - b, IntX.Pow(10, (uint)8), DivideMode.AutoNewton), (uint)numberOfDigitsRequired);
    }
}
static void Main(字符串[]args)
{
字符串引用PI="3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275900994657640789512694683983525957098258226205224894077267194782684826014769909026401363944374553050682034962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382686838689427741559918559252459539594310499725246808459872736446958486538367362226260991246080512438843904512441365497627807977156914359977001296160894416948685558484063534220722258284886481584560285060168427394522674676788952521385225499546667278239864565961163548862305774564980355936345681743241125";
秒表=新秒表();
watch.Restart();
小数x calculatedPi=PiHelper.Calculate(2500);
看,停;
Console.WriteLine(“在“+watch.elapsedmillisons+“ms”中有2500位小数的Pi”);
字符串hmmmmm=calculatedPi.ToString();
if(hmmmmm==referencePi)
Console.WriteLine(“找到Pi近似值”);
}
公共类小数
{
///十进制的整数表示法
私有只读IntX_integerPart;
///10的幂(10^X)
专用只读uint_刻度;
公共小数(整数部分,单位刻度)
{
_整数部分=整数部分;
_比例=比例;
}
公共重写字符串ToString()
{
IntX afterPoint=null;
IntX beforePoint=IntX.DivideModulo(_integerPart,IntX.Pow(10,_scale,multiplemode.AutoFht),out afterPoint,DivideMode.AutoNewton);
重新