سؤال

كيف يمكن حساب قيمة PI باستخدام C# ؟

كنت أفكر أنه سيكون من خلال وظيفة العودية, إذا كان الأمر كذلك ، ما من شأنه أن تبدو وكأنها وهل هناك أي معادلات الرياضيات إلى الوراء ؟

أنا لا صعب جدا عن الأداء ، أساسا كيفية التوجه نحو ذلك من التعلم من وجهة نظر.

هل كانت مفيدة؟

المحلول

إذا كنت تريد العودية:

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;

إذا كنت تريد دقة أفضل من ذلك ، سوف تحتاج إلى استخدام حسابي النظام العشري نوع.

إذا كنت نلقي نظرة فاحصة إلى هذا دليل جيد حقا:

أنماط البرمجة المتوازية:فهم وتطبيق أنماط موازية مع .NET Framework 4

ستجد في الصفحة 70 هذا لطيف التنفيذ (مع تغييرات طفيفة من جانبي):

static 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;
}

هناك بضعة حقا الحيل القديمة أنا مندهش أن لا نرى هنا.

atan(1) == PI/4 ، لذلك الكستناء القديم عندما بالثقة قوس الظل وظيفة الحاضر هو 4*atan(1).

لطيف جدا, ثابت-نسبة تقدير أن يجعل الغربية القديمة 22/7 تبدو مثل التراب هو 355/113 ، وهو أمر جيد أن العديد من المنازل العشرية (على الأقل ثلاثة أو أربعة ، على ما أظن).في بعض الحالات, هذا هو جيدة بما فيه الكفاية للحصول على عدد صحيح الحسابية:ضرب من قبل 355 ثم القسمة 113.

355/113 هو أيضا من السهل الالتزام الذاكرة (لبعض الناس على أي حال):العد واحد, واحد, اثنان, ثلاثة, خمسة, خمسة و تذكر أنك تسمية الأرقام في المقام و البسط (إذا نسيت الثلاثي يذهب على أعلى جزء من الفكر عادة الذهاب إلى تصويب ذلك).

علما بأن 22/7 يعطيك:3.14285714 ، وهو خطأ في الألف.

355/113 يعطيك 3.14159292 التي ليس من الخطأ حتى عشرة أجزاء من المليون.

لجنة التنسيق الإدارية.إلى /usr/وتشمل/الرياضيات.ساعة على بلدي مربع ، M_PI هو تعريف #أن:3.14159265358979323846 والتي ربما تكون جيدة بقدر ما يذهب.

الدرس من تقدير PI هو أن هناك الكثير من الطرق للقيام بذلك ، لا شيء سوف يكون من أي وقت مضى الكمال ، يجب أن نتفهمها قبل الاستخدام المقصود.

355/113 صينية قديمة تقدير ، وأعتقد أنه قبل التاريخ 22/7 قبل سنوات عديدة.كان علمتني قبل أستاذ الفيزياء عندما كنت طالبة.

عامة جيدة من خوارزميات مختلفة:

أنا لست متأكدة من تعقيد ادعى غاوس-ليجيندر-Salamin الخوارزمية في الرابط الأول (أقول O(N log^2(ن) الدخول(log(N)))).

وأشجعكم على محاولة ذلك ، على الرغم من التقارب حقا سريع.

أيضا, أنا لست متأكدا حقا لماذا تحاول تحويل بسيط جدا الإجرائية الخوارزمية إلى العودية ؟

ملاحظة أنه إذا كنت مهتما في الأداء ، ثم العمل على يحدها الدقة (عادة ما تتطلب 'ضعف', 'تعويم',...إخراج) لا معنى له ، كما هو واضح الإجابة في مثل هذه الحالة هو مجرد تضمين القيمة.

هنا هو المادة على حساب بي في C#:

http://www.boyet.com/Articles/PiCalculator.html

ما هو بي ؟ محيط الدائرة مقسوما على قطرها.

في رسومات الحاسوب يمكنك رسم/رسم دائرة مركزها في 0,0 من نقطة أولية x,y, النقطة التالية x',y' يمكن العثور عليها باستخدام صيغة بسيطة:x' = x + y / h :y' = y - x' / ساعة

ح عادة قوة 2 بحيث تقسم يمكن القيام به بسهولة مع التحول (أو طرح من الأس على مضاعفة).ح أيضا يريد أن يكون في دائرة نصف قطرها r من دائرة الخاص بك.بداية سهلة النقطة x = r, y = 0 ثم عد ج عدد من الخطوات حتى x <= 0 لرسم مكررا ثالثا من دائرة.بي 4 * c / r أو بي 4 * ج / ح

الإعادة إلى أي عمق كبير ، عادة ما يكون غير عملي على برنامج تجاري ، ولكن ذيل العودية يسمح خوارزمية يمكن التعبير عنها بشكل متكرر ، في حين نفذت حلقة.عودي خوارزميات البحث في بعض الأحيان يمكن تنفيذها باستخدام طابور بدلا من عملية كومة البحث إلى التراجع عن لطريق مسدود و تأخذ مسار آخر - هذه التراجع نقطة يمكن وضعها في قائمة الانتظار ، عمليات متعددة يمكن أن الأمم المتحدة طابور النقاط ومحاولة مسارات أخرى.

حساب مثل هذا:

x = 1 - 1/3 + 1/5 - 1/7 + 1/9  (... etc as far as possible.)
PI = x * 4

كنت قد حصلت بي !!!

هذا هو أبسط طريقة أعلم.

قيمة PI ببطء يتقاطع أن القيمة الفعلية بي (3.141592165......).إذا كنت تكرر أكثر من مرة ، كان ذلك أفضل.

وهنا لطيفة النهج (من الرئيسية ويكيبيديا على pi);فإنه يتقاطع أسرع بكثير من الصيغة البسيطة التي نوقشت أعلاه, و هي قابلة تماما العودية الحل إذا كان القصد الخاص هو السعي العودية كعملية تعلم.(على افتراض أن كنت بعد تجربة التعلم ، لن أعطي أي رمز الفعلي.)

الصيغة الأساسية هي نفسها على النحو الوارد أعلاه, ولكن هذا النهج المتوسطات جزئية مبالغ لتسريع عملية التقارب.

تحديد اثنين من المعلمة وظيفة, فطيرة(ح, ث) ، مثل أن:

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

والذي يستخدم من أجل قيم ساعة أكبر من الصفر.

الشيء الجميل في هذه الخوارزمية هو أنه يمكنك بسهولة للسخرية أنه حتى مع جدول التحقق من التعليمات البرمجية الخاصة بك كما يمكنك استكشاف النتائج التي تنتجها أكبر تدريجيا المعلمات.بحلول الوقت الذي كنت تحسب فطيرة(10,10), سيكون لديك قيمة تقريبية لـ pi هذا جيد بما فيه الكفاية بالنسبة لمعظم أغراض الهندسة.

Enumerable.Range(0, 100000000).Aggregate(0d, (tot, next) => tot += Math.Pow(-1d, next)/(2*next + 1)*4)
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;
    }

في أي إنتاج السيناريو ، أود أن تجبر لك نظرة قيمة إلى العدد المطلوب من النقاط العشرية ، وتخزينه 'const' مكان الفصول الدراسية يمكن الحصول عليه.

(إلا إذا كنت تكتب العلمية 'بي' برامج معينة...)

فيما يتعلق...

...كيفية التوجه نحو ذلك من التعلم من وجهة نظر.

هل تحاول أن تعلم أن البرنامج العلمي الأساليب ؟ أو لإنتاج إنتاج البرامج ؟ أتمنى أن المجتمع يرى هذا سؤال وليس تصيد الأخطاء.

في كلتا الحالتين أعتقد أن الكتابة الخاص بي هو حل المشكلة.ديمتري أظهرت 'الرياضيات.PI' ثابتة بالفعل.الهجوم مشكلة أخرى في نفس المساحة!تذهب العامة نيوتن تقريبية أو شيء البقعة.

@توماس Kammeyer:

علما بأن عطان(1.0) هو في كثير من الأحيان ضمنية ، حتى 4*عطان(1.0) هو ليس خوارزمية' إذا كنت استدعاء مكتبة عطان وظيفة (وهي قليلة جدا بالفعل اقترح تشرع في الواقع من خلال استبدال عطان(x) من سلسلة (أو لانهائية المنتج) ، ثم تقييم ذلك عند x=1.

أيضا ، هناك عدد قليل جدا من الحالات حيث كنت في حاجة بي عند أكثر دقة من بضع عشرات من القطع (والتي يمكن بسهولة ضمنية!).لقد عملت على التطبيقات في الرياضيات حيث لحساب بعض (معقدة) الرياضية الكائنات (التي كانت متعدد الحدود مع عدد صحيح المعاملات) ، واضطررت الى القيام بعملية حسابية على الأعداد الحقيقية (بما في ذلك الحوسبة pi) بدقة تصل إلى بضعة ملايين بت...ولكن هذه ليست متكررة جدا في الحياة الحقيقية' :)

يمكنك البحث في المثال التالي رمز.

أحب هذه الورقة, الذي يشرح كيفية حساب π على أساس سلسلة تايلور التوسع قوس الظل.

ورقة يبدأ مع افتراض بسيط هو أن

Atan(1) = π/4 راديان

Atan(x) يمكن أن يكون تكرارا المقدرة مع سلسلة تايلور

atan(x) = x - x^3/3 + س^5/5 - x^7/7 + x^9/9...

وتشير الصحيفة إلى سبب هذه ليست فعالة بشكل خاص و يذهب إلى جعل عدد من المنطقي التحسينات في تقنية.كما أنها توفر عينة البرنامج الذي يحسب π إلى بضعة آلاف من الأرقام كاملة مع التعليمات البرمجية المصدر ، بما في ذلك لانهائية-الدقة الرياضيات الروتينية المطلوبة.

الرابط التالي يوضح كيفية حساب بي ثابت على أساس تعريفها باعتبارها جزءا لا يتجزأ التي يمكن أن تكون مكتوبة الحد من الجمع ، انها مثيرة جدا للاهتمام:https://sites.google.com/site/rcorcs/posts/calculatingthepiconstant ملف "بي باعتبارها جزءا لا يتجزأ" يشرح هذه الطريقة المستخدمة في هذا المنصب.

أولا لاحظ أن C# يمكن استخدام الرياضيات.بي مجال .NET framework:

https://msdn.microsoft.com/en-us/library/system.math.pi(v=مقابل 110).aspx

ميزة جميلة هنا هو أنه كامل الدقة المزدوجة التي يمكنك إما استخدام أو مقارنة مع احتساب النتائج.علامات التبويب في ذلك URL مماثلة الثوابت C++, F# و Visual Basic.

لحساب أماكن أكثر ، يمكنك كتابة الخاصة بك الموسعة-الدقة رمز.واحد التي هي سريعة إلى رمز معقول سريعة وسهلة البرنامج هو:

Pi = 4 * [4 * ظل الزاوية القوسي (1/5) - ظل الزاوية القوسي (1/239)]

هذه الصيغة وغيرها الكثير ، بما في ذلك بعض التي تتلاقى في مثير للدهشة معدلات سريعة مثل 50 الأرقام في الأجل ، ولفرام:

ولفرام بي الصيغ

PI (π) يمكن حسابها باستخدام سلسلة لا نهاية لها.وإليك مثالين على ذلك:

غريغوري-Leibniz سلسلة:

π/4 = 1 - 1/3 + 1/5 - 1/7 + 1/9 - ...

C# الطريقة :

public static decimal GregoryLeibnizGetPI(int n)
{
    decimal sum = 0;
    decimal temp = 0;
    for (int i = 0; i < n; i++)
    {
        temp = 4m / (1 + 2 * i);
        sum += i % 2 == 0 ? temp : -temp;
    }
    return sum;
}

Nilakantha سلسلة:

π = 3 + 4 / (2x3x4) - 4 / (4x5x6) + 4 / (6x7x8) - 4 / (8x9x10) + ...

C# الطريقة:

public static decimal NilakanthaGetPI(int n)
{
    decimal sum = 0;
    decimal temp = 0;
    decimal a = 2, b = 3, c = 4;
    for (int i = 0; i < n; i++)
    {
        temp = 4 / (a * b * c);
        sum += i % 2 == 0 ? temp : -temp;
        a += 2; b += 2; c += 2;
    }
    return 3 + sum;
}

معلمة الإدخال n لكل وظائف يمثل عدد التكرار.

على Nilakantha سلسلة بالمقارنة مع غريغوري-Leibniz سلسلة يتقاطع بسرعة أكبر.الأساليب التي يمكن اختبارها مع التعليمات البرمجية التالية:

static void Main(string[] args)
{
    const decimal pi = 3.1415926535897932384626433832m;
    Console.WriteLine($"PI = {pi}");

    //Nilakantha Series
    int iterationsN = 100;
    decimal nilakanthaPI = NilakanthaGetPI(iterationsN);
    decimal CalcErrorNilakantha = pi - nilakanthaPI;
    Console.WriteLine($"\nNilakantha Series -> PI = {nilakanthaPI}");
    Console.WriteLine($"Calculation error = {CalcErrorNilakantha}");
    int numDecNilakantha = pi.ToString().Zip(nilakanthaPI.ToString(), (x, y) => x == y).TakeWhile(x => x).Count() - 2;
    Console.WriteLine($"Number of correct decimals = {numDecNilakantha}");
    Console.WriteLine($"Number of iterations = {iterationsN}");

    //Gregory-Leibniz Series
    int iterationsGL = 1000000;
    decimal GregoryLeibnizPI = GregoryLeibnizGetPI(iterationsGL);
    decimal CalcErrorGregoryLeibniz = pi - GregoryLeibnizPI;
    Console.WriteLine($"\nGregory-Leibniz Series -> PI = {GregoryLeibnizPI}");
    Console.WriteLine($"Calculation error = {CalcErrorGregoryLeibniz}");
    int numDecGregoryLeibniz = pi.ToString().Zip(GregoryLeibnizPI.ToString(), (x, y) => x == y).TakeWhile(x => x).Count() - 2;
    Console.WriteLine($"Number of correct decimals = {numDecGregoryLeibniz}");
    Console.WriteLine($"Number of iterations = {iterationsGL}");

    Console.ReadKey();
}

الإخراج التالي يدل على أن Nilakantha عوائد سلسلة ستة الصحيح العشرية بي مع مائة التكرار في حين غريغوري-Leibniz عوائد سلسلة خمسة الصحيح العشرية بي مليون التكرار:

enter image description here

بلدي رمز يمكن اختبارها >> هنا

هنا هو وسيلة لطيفة:حساب سلسلة من 1/x^2 x من 1 إلى ما تريد من أي وقت مضى - أكبر عدد - أفضل فطيرة النتيجة.مضاعفة النتيجة عن طريق 6 إلى الجذر التربيعي().هنا هو رمز في c# (الرئيسية فقط):

static void Main(string[] args)
    {
        double counter = 0;
        for (double i = 1; i < 1000000; i++)
        {

            counter = counter + (1 / (Math.Pow(i, 2)));

        }
        counter = counter * 6;
        counter = Math.Sqrt(counter);
        Console.WriteLine(counter);
    }
public double PI = 22.0 / 7.0;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top