سؤال

كيف يمكنني كتابة وظيفة ستعود PI (π) إلى عدد معين من الأماكن العشرية؟

السرعة ليست مصدر قلق. لقد كنت أبحث في http://bellard.org/pi/, ، لكنني ما زلت لا أفهم كيفية الحصول على الرقم التاسع لـ PI.

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

المحلول

في حساب التفاضل والتكامل ، يوجد شيء يسمى سلسلة Taylor والذي يوفر طريقة سهلة لحساب العديد من القيم غير المنطقية إلى الدقة التعسفية.

PI/4 = 1 - 1/3 + 1/5 - 1/7 + ...
(من http://www.math.hmc.edu/funfacts/ffiles/30001.1-3.shtml )

استمر في إضافة هذه المصطلحات حتى عدد أرقام الدقة التي تريد الاستقرار.

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


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

نصائح أخرى

هناك العديد من الخوارزميات التقريب الرقمي لـ π.

كبديل لطريقة Jeffh في تخزين كل الاختلاف ، يمكنك فقط تخزين الحد الأقصى لعدد الأرقام وقطع ما لا تحتاجه:

#include <string>
#include <iostream>
using std::cout; using std::endl; using std::string;

// The first 99 decimal digits taken from:
// http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html
// Add more as needed.
const string pi =
  "1415926535"
  "8979323846"
  "2643383279"
  "5028841971"
  "6939937510"
  "5820974944"
  "5923078164"
  "0628620899"
  "8628034825"
  "342117067";

// A function in C++ that returns pi to X places
string CalcPi(const size_t decimalDigitsCount) 
{
  string returnValue = "3";
  if (decimalDigitsCount > 0)
  {
    returnValue += "." + pi.substr(0, decimalDigitsCount);
  }
  return returnValue;
} 

int main()
{
  // Loop through all the values of "pi at x digits" that we have. 
  for (size_t i = 0; i <= pi.size(); ++i) 
  {
    cout << "pi(" << i << "): " << CalcPi(i) << endl;
  } 
}

http://codepad.org/6mqda1zj

أعتقد أن الخوارزمية التي تبحث عنها هي ما يعرف باسم "خوارزمية الحنفية". نوع واحد هو BBP (بيلي بوروين-بلوفي) الصيغة.

أعتقد أن هذا ما تبحث عنه.

محاولة "حساب الرقم n'th من Pi في أي قاعدة في O (n^2)"ربما تكون أسرع خوارزمية معروفة لا تتطلب تعسفيًا (اقرأ تسربت) تعويم الدقة ، ويمكن أن تعطيك النتيجة مباشرة في القاعدة 10 (أو أي أخرى).

"π في مجموعة Mandelbrot"يستكشف العلاقة الغريبة بين سلسلة من النقاط على الطائرة المعقدة وكيف حساب" رقم Mandelbrot "(لعدم وجود مصطلح أفضل ... عدد التكرارات المطلوبة لتحديد أن النقاط في التسلسل ليست أعضاء في Mandelbrot مجموعة) تتعلق بـ PI.

عملي؟ على الاغلب لا.

غير متوقع ومثيرة للاهتمام؟ أعتقد ذلك.

هل أنت على استعداد للبحث عن القيم بدلاً من حسابها؟

بما أنك لم تحدد صراحة أن وظيفتك يجب أن تفعل ذلك حساب القيم ، إليك حل ممكن إذا كنت على استعداد للحصول على حد أعلى على عدد الأرقام التي يمكن "حسابها":

// Initialize pis as far out as you want. 
// There are lots of places you can look up pi out to a specific # of digits.
double pis[] = {3.0, 3.1, 3.14, 3.141, 3.1416}; 

/* 
 * A function that returns pi out to a number of digits (up to a point)
 */
double CalcPi(int x)
{
    // NOTE: Should add range checking here. For now, do not access past end of pis[]
    return pis[x]; 
}

int main()
{
    // Loop through all the values of "pi at x digits" that we have.
    for (int ii=0; ii<(int)sizeof(pis)/sizeof(double); ii++)
    {
        double piAtXdigits = CalcPi(ii);
    }
}

إن كتابة Calcpi () بهذه الطريقة (إذا تلبي احتياجاتك) لها فائدة جانبية تتمثل في أن تصرخ بسرعة مقابل أي قيمة x ضمن الحد الأعلى.

سأبدأ بالصيغة

pi = 16 arctan (1/5) - 4 arctan (1/239)

ستجد Google بسهولة دليلًا على هذه الصيغة التي يمكن أن يفهمها البشر العاديون ، وصيغة لحساب وظيفة الظل القوس. سيسمح لك ذلك بحساب بضعة آلاف من الأرقام العشرية من PI بسهولة وسرعة.

يمكنك معرفة الدقة بناءً على المدة الأخيرة التي أضفتها (أو طرحها). نظرًا لأن سعة كل مصطلح في تسلسل آلان تتناقص دائمًا ويتناوب كل مصطلح في العلامة ، فلن يتغير المبلغ أكثر من الفترة الأخيرة.

ترجمة هذا الثرثرة: بعد إضافة 1/5 ، لن يتغير المبلغ أكثر من 1/5 ، لذلك فأنت دقيق في غضون 1/5. بالطبع ، سيتعين عليك مضاعفة هذا بمقدار 4 ، لذا فأنت دقيق حقًا حتى 4/5.

لسوء الحظ ، لا تترجم الرياضيات دائمًا بسهولة إلى أرقام عشرية.

سنتي ... قد لا يكون هذا الأسرع ، لكنني أعتقد أنه من السهل جدًا فهمه. توصلت إلى ذلك بنفسي خلال محاضرة الرياضيات ، ولم أره حقًا في أي مكان آخر في الأدب. إما أن أكون عبقريًا أو غبيًا حقًا أو لا تولي اهتمامًا لقراءة الكتب حول الرياضيات ، أو كل ما سبق ... :)

على أي حال ... ابدأ مع دائرة الوحدة. نحن نعلم أن x^2+y^2 = 1 ، لذا y = sqrt (1-x^2). نعلم أيضًا أن مساحة وحدة الوحدة هي PI. إذا أخذنا الآن جزءًا لا يتجزأ من وظيفة SQRT (1-X^2) في النطاق من 0 إلى 1 ، فسوف نحصل على ربع PI. لذا اضربها بمقدار 4 للحصول على PI:

PI formula

إذا حاولنا حل هذا من الناحية التحليلية ، فأنا متأكد من أننا سنستعيد PI. لكن من السهل جدًا كتابة برنامج لحله عدديًا. التالي في ج:

#include <math.h>
#include <stdio.h>

void main(void) {
    double interval=0.0000001,area=0,x,y;

    for (x=0; x<1; x+=interval)
        area+=4*interval*sqrt(1-x*x);

    printf("pi ~ %.20f\n",area);
}

تشغيله مع الإعداد أعلاه ل interval, ، نحن نحصل:

pi ~ 3.14159285415672595576

لذلك 10،000،000 تكرار يعطي 6 العشرية الصحيحة. ليس الأكثر كفاءة ، لكنه طفلي ... :)

pi = function () {
    let pi = 3;
    let a = 3;
    let even = false;
    let turn;

    while (a <= 90000) {
        turn = (4/((Math.pow(a, 3)) - (a)));

        if(even){
            turn = turn*-1;
            even = false;
        } else {
            even = true;
        }
        pi = pi + turn;
        a = a + 2;
    }
    return pi;
};

النظر في هذا رسم تقريبي ، لكنه نهج واضح يمكن أن ينفذه المبتدئ.

int x = 9;
double pi = double(22/7);
String piAsString = pi.toString();
String valueAtXPosition = piAsString.subString(x, x+1);
int valueAtXPosAsInt = Integer.parseInt(valueAtXPosition);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top