मूल्य प्राप्त करने का सबसे तेज़ तरीका क्या है ??

समाधान किसी भी भाषा में स्वागत है। :-) मैं व्यक्तिगत चुनौती के रूप में, मूल्य प्राप्त करने का सबसे तेज़ तरीका ढूंढ रहा हूं। अधिक विशेष रूप से मैं उन तरीकों का उपयोग कर रहा हूं जिनमें #define डी स्थिरांक जैसे M_PI का उपयोग शामिल नहीं है, या संख्या को हार्ड-कोडिंग करना शामिल नहीं है।

नीचे दिया गया कार्यक्रम विभिन्न तरीकों का परीक्षण करता है जिन्हें मैं जानता हूं। इनलाइन असेंबली संस्करण, सिद्धांत रूप में, सबसे तेज़ विकल्प है, हालांकि स्पष्ट रूप से पोर्टेबल नहीं है; मैंने इसे अन्य संस्करणों की तुलना करने के लिए आधारभूत आधार के रूप में शामिल किया है। मेरे परीक्षणों में, अंतर्निर्मित के साथ, 4 * atan (1) संस्करण जीसीसी 4.2 पर सबसे तेज़ है, क्योंकि यह atan (1) को निरंतर में स्वतः फोल्ड करता है । -fno-builtin निर्दिष्ट के साथ, atan2 (0, -1) संस्करण सबसे तेज़ है।

यहां मुख्य परीक्षण कार्यक्रम ( pitimes.c ) है:

#include 
#include 
#include 

#define ITERS 10000000
#define TESTWITH(x) {                                                       \
    diff = 0.0;                                                             \
    time1 = clock();                                                        \
    for (i = 0; i < ITERS; ++i)                                             \
        diff += (x) - M_PI;                                                 \
    time2 = clock();                                                        \
    printf("%s\t=> %e, time => %f\n", #x, diff, diffclock(time2, time1));   \
}

static inline double
diffclock(clock_t time1, clock_t time0)
{
    return (double) (time1 - time0) / CLOCKS_PER_SEC;
}

int
main()
{
    int i;
    clock_t time1, time2;
    double diff;

    /* Warmup. The atan2 case catches GCC's atan folding (which would
     * optimise the ``4 * atan(1) - M_PI'' to a no-op), if -fno-builtin
     * is not used. */
    TESTWITH(4 * atan(1))
    TESTWITH(4 * atan2(1, 1))

#if defined(__GNUC__) && (defined(__i386__) || defined(__amd64__))
    extern double fldpi();
    TESTWITH(fldpi())
#endif

    /* Actual tests start here. */
    TESTWITH(atan2(0, -1))
    TESTWITH(acos(-1))
    TESTWITH(2 * asin(1))
    TESTWITH(4 * atan2(1, 1))
    TESTWITH(4 * atan(1))

    return 0;
}

और इनलाइन असेंबली सामान ( fldpi.c ), यह नोट करते हुए कि यह केवल x86 और x64 सिस्टम के लिए काम करेगा:

double
fldpi()
{
    double pi;
    asm("fldpi" : "=t" (pi));
    return pi;
}

और एक बिल्ड स्क्रिप्ट जो सभी कॉन्फ़िगरेशन बनाता है जो मैं परीक्षण कर रहा हूं ( build.sh ):

#!/bin/sh
gcc -O3 -Wall -c           -m32 -o fldpi-32.o fldpi.c
gcc -O3 -Wall -c           -m64 -o fldpi-64.o fldpi.c

gcc -O3 -Wall -ffast-math  -m32 -o pitimes1-32 pitimes.c fldpi-32.o
gcc -O3 -Wall              -m32 -o pitimes2-32 pitimes.c fldpi-32.o -lm
gcc -O3 -Wall -fno-builtin -m32 -o pitimes3-32 pitimes.c fldpi-32.o -lm
gcc -O3 -Wall -ffast-math  -m64 -o pitimes1-64 pitimes.c fldpi-64.o -lm
gcc -O3 -Wall              -m64 -o pitimes2-64 pitimes.c fldpi-64.o -lm
gcc -O3 -Wall -fno-builtin -m64 -o pitimes3-64 pitimes.c fldpi-64.o -lm

विभिन्न कंपाइलर झंडे के बीच परीक्षण के अलावा (मैंने 64-बिट के मुकाबले 32-बिट की तुलना की है, क्योंकि ऑप्टिमाइज़ेशन अलग हैं), मैंने परीक्षणों के क्रम को स्विच करने का भी प्रयास किया है। atan2 (0, -1) संस्करण हर बार शीर्ष पर आता है, हालांकि।

0
जोड़ा संपादित
विचारों: 31
@Zeus इस विशिष्ट मामले में, मेरा प्रश्न वास्तव में एक "मजेदार" माइक्रो-ऑप्टिमाइज़ेशन प्रश्न (जो, इन दिनों, शायद प्रोग्रामिंग पहेलियाँ और कोड गोल्फ ), लेकिन" पीआई की गणना करने का सबसे तेज़ तरीका "का सामान्य आधार इस प्रश्न को यहां रखने के लिए पर्याप्त उपयोगी प्रतीत होता है। तो, कुछ स्तर पर, मैं संभवतया पुनर्मूल्यांकन करूंगा कि मुझे माइक्रो-ऑप्टिमाइज़ेशन से संबंधित है या नहीं, इसके बावजूद मुझे सबसे अच्छा एल्गोरिदमिक उत्तर (शायद nlucaroni's one) स्वीकार करना चाहिए या नहीं।
जोड़ा लेखक Chris Jester-Young, स्रोत
@ HopelessN00b अंग्रेजी की बोली में मैं बोलता हूं, "अनुकूलन" वर्तनी है " एस ", नहीं" ज़ेड "(जिसे" ज़ेड "के रूप में उच्चारण किया जाता है, बीटीडब्ल्यू," ज़ी "नहीं ;-))। (यदि आप समीक्षा इतिहास देखते हैं तो यह पहली बार नहीं है कि मुझे इस तरह के संपादन को वापस करना पड़ा है।)
जोड़ा लेखक Chris Jester-Young, स्रोत
nlucaroni का जवाब 100 अपवॉट्स (बधाई) तक पहुंच गया है, इसलिए शायद यह हरे रंग के निशान के लिए एक अच्छा मुद्दा है। का आनंद लें! (हालांकि, चूंकि यह समुदाय विकी और सब कुछ है, इसलिए यह कोई प्रतिनिधि नहीं बना रहा है, इसलिए यह भी सुनिश्चित नहीं है कि अगर नलबुकोनी इसे भी नोटिस करेगी।)
जोड़ा लेखक Chris Jester-Young, स्रोत
जोड़ा लेखक Chris Jester-Young, स्रोत
@erik: सभी भाषाओं में अंतर्निहित निरंतर स्थिरता नहीं है जैसे M_PI । मैं पीआई के एक (फ़्लोटिंग-पॉइंट) मान प्राप्त करने के लिए "आधिकारिक" तरीका खोजने की कोशिश कर रहा था (सिद्धांत में) विभिन्न भाषाओं (और / या उनके अंतर्निर्मित पुस्तकालयों) में काम करता है। मेरी वर्तमान पसंदीदा विधि atan2 (0, -1) का उपयोग कर रही है, लेकिन शायद बेहतर तरीके हैं।
जोड़ा लेखक Chris Jester-Young, स्रोत
@signonsridhar नहीं, हम केवल गणना विधियों के बारे में बात कर रहे हैं जो दो-परिशुद्धता के लिए छोटा होने पर M_PI के समान परिणाम देते हैं।
जोड़ा लेखक Chris Jester-Young, स्रोत
सी ++ मेटाप्रोग्रामिंग में ऐसा करने का एक तरीका होना चाहिए। रन टाइम वास्तव में अच्छा होगा, लेकिन संकलन समय नहीं होगा।
जोड़ा लेखक David Thornley, स्रोत
केवल एक समाधान है जो पूर्व-गणना स्थिर पीआई से तेज़ है: सूत्रों में दिखाई देने वाले सभी मानों की पूर्व-गणना करें, उदा। जब परिधि की आवश्यकता होती है, तो आप पीआईआई को रनटाइम में 2 बार गुणा करने के बजाय 2 * पीआई की गणना कर सकते हैं।
जोड़ा लेखक ern0, स्रोत
सवाल यह है: आप नहीं निरंतर उपयोग क्यों करना चाहते हैं? जैसे या तो पुस्तकालय द्वारा परिभाषित किया गया है या स्वयं? कंप्यूटिंग पीआई सीपीयू चक्रों का अपशिष्ट है, क्योंकि इस समस्या को दैनिक गणनाओं के लिए आवश्यक से अधिक महत्वपूर्ण अंकों के लिए बार-बार हल किया गया है
जोड़ा लेखक Tilo, स्रोत
आप एमएटीआई का उपयोग करने से अलग एटान (1) का उपयोग क्यों करते हैं? मैं समझूंगा कि आप ऐसा क्यों करना चाहते हैं यदि आप केवल अंकगणितीय परिचालनों का उपयोग करते हैं, लेकिन एटान के साथ मुझे बिंदु दिखाई नहीं देता है।
जोड़ा लेखक erikkallen, स्रोत
इसे आदर्श रूप से मिस्टिकियल का ध्यान रखना चाहिए, क्योंकि वह सबसे बड़ी संख्या में अंकों की गणना करने के लिए विश्व रिकॉर्ड धारक है। stackoverflow.com/questions/14283270/…
जोड़ा लेखक Team Upvote, स्रोत
@ क्रिसजेस्टर-यंग नोप। यह इरादा नहीं है .. मैंने हाल ही में नियमों में और अधिक पढ़ना शुरू कर दिया .. और सोचा कि मैं उन धागे पर अपना हिस्सा करूंगा जो मैं उन उपयोगकर्ताओं को याद दिलाने के लिए करता हूं जो लंबे समय के फ्रेम को भूल गए हैं। मैं यहां पुलिस बनने की कोशिश नहीं कर रहा हूं। क्षमा करें अगर मैं कठोर परिश्रम में आया।
जोड़ा लेखक Zeus, स्रोत
9801 / (1103? 8) .. छह दशमलव स्थान देता है .. यह पीआई की गणना करने का सबसे तेज़ तरीका है? = 3.14159273
जोड़ा लेखक signonsridhar, स्रोत
@ क्रिस जेस्टर-यंग वेल मैंने अभी रामानुजन पर एक वीडियो देखा जिसने पीआई की गणना करने के लिए इस तरह दिया। तो मैंने अभी इसे साझा किया:>
जोड़ा लेखक signonsridhar, स्रोत

20 उत्तर

यहां उच्च विद्यालय में सीआई की गणना करने के लिए तकनीक का एक सामान्य विवरण दिया गया है।

मैं केवल इसे साझा करता हूं क्योंकि मुझे लगता है कि यह इतना आसान है कि कोई भी इसे याद रख सके, अनिश्चित काल तक, साथ ही यह आपको "मोंटे-कार्लो" विधियों की अवधारणा सिखाता है - जो उत्तर में आने के सांख्यिकीय तरीके हैं जो तुरंत प्रकट नहीं होते हैं यादृच्छिक प्रक्रियाओं के माध्यम से deducible।

एक वर्ग बनाएं, और उस वर्ग के अंदर एक चतुर्भुज (सेमीफाइनल का एक चौथाई) डालें (वर्ग के किनारे के बराबर त्रिज्या वाला चतुर्भुज, इसलिए यह जितना संभव हो उतना वर्ग भरता है)

अब वर्ग पर एक डार्ट फेंक दें, और रिकॉर्ड करें जहां यह भूमि है - यानी, वर्ग के अंदर कहीं भी एक यादृच्छिक बिंदु चुनें। बेशक, यह वर्ग के अंदर उतरा, लेकिन यह अर्द्ध सर्कल के अंदर है? इस तथ्य को रिकॉर्ड करें।

इस प्रक्रिया को कई बार दोहराएं - और आप पाएंगे कि कुल संख्या फेंकने वाले सेमीफाइनल के अंदर बिंदुओं की संख्या का अनुपात है, इस अनुपात x को कॉल करें।

चूंकि वर्ग का क्षेत्र आर बार आर है, आप यह समझ सकते हैं कि अर्ध सर्कल का क्षेत्र x गुणा आर गुना आर (यानी, x गुणा आर वर्ग) है। इसलिए एक्स टाइम्स 4 आपको पीआई देगा।

यह उपयोग करने के लिए एक त्वरित विधि नहीं है। लेकिन यह मोंटे कार्लो विधि का एक अच्छा उदाहरण है। और यदि आप चारों ओर देखते हैं, तो आप पाएंगे कि अन्यथा आपके कम्प्यूटेशनल कौशल के बाहर कई समस्याएं इस तरह के तरीकों से हल की जा सकती हैं।

0
जोड़ा
यह वह तरीका है जिसका उपयोग हम स्कूल में जावा परियोजना में पीआई की गणना करने के लिए करते थे। एक्स, वाई निर्देशांक और अधिक 'डार्ट्स' के साथ आने के लिए हमने एक यादृच्छिक यंत्र का उपयोग किया, हमने पी के करीब फेंक दिया।
जोड़ा लेखक Jeff Keslinke, स्रोत

यदि सबसे तेज़ से आप कोड में टाइप करने के लिए सबसे तेज़ हैं, तो यहां golfscript समाधान है:

;''6666,-2%{2+.2/@*\/10.3??2*+}*`1000<~\;
0
जोड़ा

जैसा कि बताया गया है, मोंटे कार्लो विधि , कुछ महान अवधारणाओं को लागू करता है लेकिन यह स्पष्ट रूप से सबसे तेज़ नहीं है - किसी भी उचित उपयोग से नहीं, एक लंबे शॉट से नहीं। साथ ही, यह सब इस बात पर निर्भर करता है कि आप किस प्रकार की सटीकता की तलाश में हैं। सबसे तेज़ पीआई मुझे पता है कि हार्ड कोड कोड हैं। पीआई और पीआई [पीडीएफ] , बहुत सारे सूत्र हैं।

यहां एक विधि है जो जल्दी से अभिसरण (प्रति पुनरावृत्ति ~ 14digits)। वर्तमान सबसे तेज़ एप्लिकेशन, PiFast , इस सूत्र का उपयोग करता है FFT के साथ। मैं सिर्फ सूत्र लिखूंगा, क्योंकि कोड सीधे आगे है। यह सूत्र लगभग रामानुजन और चुडनोव्स्की द्वारा खोजा गया था द्वारा पाया गया था। वास्तव में यह संख्या के कई बिलियन अंकों की गणना कैसे की गई है - इसलिए यह उपेक्षा करने का एक तरीका नहीं है। फॉर्मूला तेजी से बह जाएगा क्योंकि हम फैक्टोरियल को विभाजित कर रहे हैं, फिर शब्दों को हटाने के लिए गणना करने में देरी होगी।

यहां छवि विवरण दर्ज करें

यहां छवि विवरण दर्ज करें

कहा पे,

यहां छवि विवरण दर्ज करें

नीचे ब्रेंट? सैलामिन एल्गोरिदम है। विकिपीडिया का उल्लेख है कि जब ए और बी 'पर्याप्त करीब' होते हैं तो (ए + बी) ^ 2 / 4t पीआई का अनुमान होगा। मुझे यकीन नहीं है कि 'पर्याप्त नजदीक' का मतलब क्या है, लेकिन मेरे परीक्षणों से, एक पुनरावृत्ति को 2 डिजिट मिलते हैं, दो को 7 मिलते हैं, और तीन में 15 होते हैं, बेशक यह युगल के साथ होता है, इसलिए इसमें इसके प्रतिनिधित्व के आधार पर त्रुटि हो सकती है और ' सच 'गणना अधिक सटीक हो सकती है।

let pi_2 iters =
    let rec loop_ a b t p i =
        if i = 0 then a,b,t,p
        else
            let a_n = (a +. b) /. 2.0 
            and b_n = sqrt (a*.b)
            and p_n = 2.0 *. p in
            let t_n = t -. (p *. (a -. a_n) *. (a -. a_n)) in
            loop_ a_n b_n t_n p_n (i - 1)
    in 
    let a,b,t,p = loop_ (1.0) (1.0 /. (sqrt 2.0)) (1.0/.4.0) (1.0) iters in
    (a +. b) *. (a +. b) /. (4.0 *. t)

आखिरकार, कुछ पीआई गोल्फ (800 अंक) के बारे में कैसे? 160 अक्षर!

int a=10000,b,c=2800,d,e,f[2801],g;main(){for(;b-c;)f[b++]=a/5;for(;d=0,g=c*2;c-=14,printf("%.4d",e+d/a),e=d%a)for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);}
0
जोड़ा
मान लीजिए कि आप स्वयं को पहले लागू करने की कोशिश कर रहे हैं, क्या एसक्यूआर (के 3) कोई समस्या नहीं होगी? मुझे पूरा यकीन है कि यह एक अपरिमेय संख्या को समाप्त कर देगा जो आपको अनुमान लगाएगा (आईआईआरसी, सभी जड़ें जो पूरी संख्या नहीं हैं) तर्कहीन हैं। यदि आप अनंत सटीक अंकगणित का उपयोग कर रहे हैं, तो बाकी सब कुछ बहुत सीधी-आगे दिखता है लेकिन वह वर्ग रूट एक सौदा ब्रेकर है। दूसरे में एक वर्ग भी शामिल है।
जोड़ा लेखक Bill K, स्रोत
मेरे अनुभव में, 'पर्याप्त करीब' आमतौर पर इसका मतलब है कि एक टेलर श्रृंखला अनुमान शामिल है।
जोड़ा लेखक Stephen, स्रोत

मुझे वास्तव में यह प्रोग्राम पसंद है, जो अपने क्षेत्र को देखकर पीआई का अनुमान लगाता है :-)

आईओसीसीसी 1 9 88: westley.c

#define _ -F<00||--F-OO--;
int F=00,OO=00;main(){F_OO();printf("%1.3f\n",4.*-F/OO/OO);}F_OO()
{
            _-_-_-_
       _-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_
  _-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
  _-_-_-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_
        _-_-_-_-_-_-_-_
            _-_-_-_
}
0
जोड़ा
यदि आप _ -F <00 || --F-OO के साथ _ को प्रतिस्थापित करते हैं - तो इसका पालन करना आसान होना चाहिए :-)
जोड़ा लेखक Pat, स्रोत
यह कार्यक्रम 1 99 8 में बहुत अच्छा था, लेकिन टूट गया क्योंकि आधुनिक प्रीप्रोसेसर इस तरह की चीजों को काम करने से रोकने के लिए मैक्रो विस्तार के आसपास रिक्त स्थान डालने के साथ अधिक उदार हैं। दुर्भाग्य से यह एक अवशेष है।
जोड़ा लेखक Chris Lutz, स्रोत
यह यहाँ 0.25 प्रिंट करता है.-
जोड़ा लेखक Johannes Schaub - litb, स्रोत
@Pat अगर आप घायल हो गए तो मैंने इसे क्यों संपादित किया क्योंकि यह मैंने एलक्यूपी कतार में यह जवाब देखा था stackoverflow.com/review/low - गुणवत्ता-पद / 16750528 , इसलिए हटाने से बचने के लिए मैंने उत्तर के लिंक में कोड जोड़ा।
जोड़ा लेखक Petter Friberg, स्रोत
इच्छित व्यवहार प्राप्त करने के लिए - पारंपरिक-सीपीपी cpp पास करें।
जोड़ा लेखक Nietzche-jou, स्रोत
या, यदि आप _ को बदलते हैं "अगर (पिछला वर्ण है '-') {ओओ--;} एफ--;"
जोड़ा लेखक FryGuy, स्रोत

पुराने दिनों में, छोटे शब्द के आकार और धीमी या गैर-मौजूद फ्लोटिंग-पॉइंट ऑपरेशंस के साथ, हम इस तरह की चीजें करते थे:

/* Return approximation of n * PI; n is integer */
#define pi_times(n) (((n) * 22) / 7)

उन अनुप्रयोगों के लिए जिन्हें बहुत सटीकता की आवश्यकता नहीं है (उदाहरण के लिए वीडियो गेम), यह बहुत तेज़ है और पर्याप्त सटीक है।

0
जोड़ा
अधिक सटीकता के लिए 355/113 का उपयोग करें। शामिल संख्याओं के आकार के लिए बहुत सटीक।
जोड़ा लेखक David Thornley, स्रोत
जिज्ञासा से बाहर: 22/7 3 + 1/7 है
जोड़ा लेखक Agnius Vasiliauskas, स्रोत

बीबीपी फॉर्मूला आपको nth अंक की गणना करने की अनुमति देता है - बेस 2 (या 16 में) ) - पहले पिछले एन -1 अंकों से भी परेशान किए बिना :)

0
जोड़ा

यह संस्करण (डेल्फी में) कुछ खास नहीं है, लेकिन यह संस्करण से कम से कम तेज़ है निक हॉज ने अपने ब्लॉग पर पोस्ट किया :)। मेरी मशीन पर, 3.14159265 25879 (सटीक भाग बोल्ड में है) का मान देते हुए, एक अरब पुनरावृत्तियों को करने में लगभग 16 सेकंड लगते हैं।

program calcpi;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  start, finish: TDateTime;

function CalculatePi(iterations: integer): double;
var
  numerator, denominator, i: integer;
  sum: double;
begin
  {
  PI may be approximated with this formula:
  4 * (1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 .......)
  //}
  numerator := 1;
  denominator := 1;
  sum := 0;
  for i := 1 to iterations do begin
    sum := sum + (numerator/denominator);
    denominator := denominator + 2;
    numerator := -numerator;
  end;
  Result := 4 * sum;
end;

begin
  try
    start := Now;
    WriteLn(FloatToStr(CalculatePi(StrToInt(ParamStr(1)))));
    finish := Now;
    WriteLn('Seconds:' + FormatDateTime('hh:mm:ss.zz',finish-start));
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
0
जोड़ा

यदि यह आलेख सत्य है, तो एल्गोरिदम जिसे Bellard बनाया गया है, सबसे तेज़ उपलब्ध हो सकता है। उन्होंने एक डेस्कटॉप पीसी का उपयोग कर 2.7 ट्रिलियन अंकों में पीआई बनाया है!

...and he has published his work here

अच्छा काम Bellard, आप एक अग्रणी हैं!

http://www.theregister.co.uk/2010/01/06/ very_long_pi /

0
जोड़ा
बेलर्ड ने कई तरीकों से अग्रणी किया ... सबसे पहले संभवतः पहले निष्पादन योग्य कंप्रेसर (लगता है कि यूपीएक्स क्या करता है, फिर 80 के दशक में वापस फ्लिप करें), और निश्चित रूप से, दोनों क्यूईएमयू और एफएफएमपीईजी का व्यापक रूप से उपयोग किया जाता है । ओह, और उनकी आईओसीसीसी प्रविष्टि .... :- पी
जोड़ा लेखक Chris Jester-Young, स्रोत

यदि आप सन्निकटन का उपयोग करने के इच्छुक हैं, तो 355/113 6 दशमलव अंकों के लिए अच्छा है, और इसमें पूर्णांक अभिव्यक्तियों के साथ उपयोग करने का अतिरिक्त लाभ है। यह इन दिनों के रूप में महत्वपूर्ण नहीं है, क्योंकि "फ्लोटिंग पॉइंट गणित सह-प्रोसेसर" का कोई मतलब नहीं है, लेकिन यह एक बार काफी महत्वपूर्ण था।

0
जोड़ा

पूर्णता के हित में, एक सी ++ टेम्पलेट संस्करण, जो एक अनुकूलित निर्माण के लिए संकलन समय पर पीआई की गणना करेगा और एक ही मूल्य में इनलाइन होगा।

#include 

template
struct sign
{
    enum {value = (I % 2) == 0 ? 1 : -1};
};

template
struct pi_calc
{
    inline static double value ()
    {
        return (pi_calc::value() + pi_calc::value ()) / 2.0;
    }
};

template
struct pi_calc<0, J>
{
    inline static double value ()
    {
        return (sign::value * 4.0) / (2.0 * J + 1.0) + pi_calc<0, J-1>::value ();
    }
};


template<>
struct pi_calc<0, 0>
{
    inline static double value ()
    {
        return 4.0;
    }
};

template
struct pi
{
    inline static double value ()
    {
        return pi_calc::value ();
    }
};

int main ()
{
    std::cout.precision (12);

    const double pi_value = pi<10>::value ();

    std::cout << "pi ~ " << pi_value << std::endl;

    return 0;
}

Note for I > 10, optimised builds can be slow, likewise for non-optimised runs. For 12 iterations I believe there are around 80k calls to value() (in the absence of memoisation).

0
जोड़ा
@ sebastião-miranda लीबनिज़ का सूत्र , औसत औसत त्वरण में अभिसरण में सुधार करता है। pi_calc <0, J> सूत्र से प्रत्येक क्रमिक अवधि की गणना करता है और गैर-विशिष्ट pi_calc औसत की गणना करता है।
जोड़ा लेखक jon-hanson, स्रोत
खैर, यह 9 डीपी के लिए सही है। क्या आप किसी चीज़ पर ऑब्जेक्ट कर रहे हैं या सिर्फ अवलोकन कर रहे हैं?
जोड़ा लेखक jon-hanson, स्रोत
मैं इसे चलाता हूं और "पीआई ~ 3.14159265383" प्राप्त करता हूं
जोड़ा लेखक maxwellb, स्रोत
पीआई की गणना करने के लिए यहां इस्तेमाल किए गए एल्गोरिदम का नाम क्या है?
जोड़ा लेखक Sebastião Miranda, स्रोत

गणना कर रहा है? सर्कल क्षेत्र से :-)

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

<input id="range" type="range" min="10" max="960" value="10" step="50" oninput="calcPi()">

<div id="cont"></div> <script> function generateCircle(width) { var c = width/2; var delta = 1.0; var str = ""; var xCount = 0; for (var x=0; x <= width; x++) { for (var y = 0; y <= width; y++) { var d = Math.sqrt((x-c)*(x-c) + (y-c)*(y-c)); if (d > (width-1)/2) { str += '.'; } else { xCount++; str += 'o'; } str += " " } str += "\n"; } var pi = (xCount * 4) / (width * width); return [str, pi]; } function calcPi() { var e = document.getElementById("cont"); var width = document.getElementById("range").value; e.innerHTML = "

Generating circle...

";
    setTimeout(function() {
        var circ = generateCircle(width);
        e.innerHTML  = "
" + "? = " + circ[1].toFixed(2) + "\n" + circ[0] +"
";
    }, 200);
}
calcPi();
</script>
</div> </div>

0
जोड़ा

निम्नलिखित उत्तरों सबसे तेज़ संभव तरीके से इसे कैसे करें - कम से कम कंप्यूटिंग प्रयास के साथ। भले ही आपको उत्तर पसंद न हो, आपको यह स्वीकार करना होगा कि यह वास्तव में पीआई के मूल्य प्राप्त का सबसे तेज़ तरीका है।

पीआई का मूल्य प्राप्त करने के लिए सबसे तेज़ तरीका है:

  1. अपनी पसंदीदा प्रोग्रामिंग भाषा चुनें
  2. इसे मैथ लाइब्रेरी लोड करें
  3. और पाते हैं कि पीआई पहले ही परिभाषित है !! इसका उपयोग करने के लिए तैयार ..

यदि आपके पास हाथ में एक गणित पुस्तकालय नहीं है ..

दूसरा सबसे तेज़ तरीका (अधिक सार्वभौमिक समाधान) है:

इंटरनेट पर पीआई देखें, उदा। यहाँ:

http://www.eveandersson.com/pi/digits/1000000 (1 million digits .. what's your floating point precision? )

या इधर:

http://3.141592653589793238462643383279502884197169399375105820974944592.com/

या इधर:

http://en.wikipedia.org/wiki/Pi

जो भी सटीक अंकगणित आप उपयोग करना चाहते हैं, उसके लिए आवश्यक अंकों को ढूंढना वास्तव में तेज़ है, और निरंतर परिभाषित करके, आप यह सुनिश्चित कर सकते हैं कि आप बहुमूल्य CPU समय बर्बाद न करें।

न केवल यह आंशिक रूप से विनोदी जवाब है, बल्कि हकीकत में, यदि कोई आगे बढ़ेगा और वास्तविक अनुप्रयोग में पीआई के मूल्य की गणना करेगा .. यह CPU समय का एक बड़ा बड़ा अपशिष्ट होगा, है ना? कम से कम मुझे इसकी गणना करने की कोशिश करने के लिए एक असली एप्लिकेशन नहीं दिख रहा है।

प्रिय मॉडरेटर: कृपया ध्यान दें कि ओपी ने पूछा: "सबसे तेज़ तरीका पीआई का मूल्य प्राप्त करने के लिए"

0
जोड़ा

यदि आप मूल्य के अनुमान के गणना करना चाहते हैं? (किसी कारण से), आपको बाइनरी निष्कर्षण एल्गोरिदम का प्रयास करना चाहिए। बेलर्ड का बीबीपी ओ (एन ^ 2) में पीआई देता है।


यदि आप मूल्य के अनुमान के प्राप्त करना चाहते हैं? गणना करने के लिए, फिर:

PI = 3.141592654

अनुमोदित, यह केवल एक अनुमान है, और पूरी तरह से सटीक नहीं है। यह 0.00000000004102 से थोड़ा अधिक बंद है। (चार दस ट्रिलियनवां, लगभग 4 / 10,000,000,000 )।


यदि आप गणित के साथ करना चाहते हैं, तो अपने आप को एक पेंसिल और पेपर या कंप्यूटर बीजगणित पैकेज प्राप्त करें, और उपयोग करें? सटीक मान,?

यदि आप वास्तव में एक सूत्र चाहते हैं, तो यह मजेदार है:

? = - i ln (-1)

0
जोड़ा
आपका सूत्र इस बात पर निर्भर करता है कि आप जटिल विमान में एलएन कैसे परिभाषित करते हैं। यह जटिल विमान में एक लाइन के साथ गैर-संगत होना चाहिए, और उस रेखा के लिए नकारात्मक वास्तविक धुरी होने के लिए यह काफी आम है।
जोड़ा लेखक erikkallen, स्रोत

बस इस पूरे में आया जो पूर्णता के लिए यहां होना चाहिए:

पीट में पीआई की गणना करें

इसकी बजाय अच्छी संपत्ति है कि प्रोग्राम को बड़ा बनाने में परिशुद्धता में सुधार किया जा सकता है।

Here's some insight into the language itself

0
जोड़ा

डी के साथ संकलन समय पर पीआई की गणना करें।

( DSource.org से कॉपी किया गया)

/** Calculate pi at compile time
 *
 * Compile with dmd -c pi.d
 */
module calcpi;

import meta.math;
import meta.conv;

/** real evaluateSeries!(real x, real metafunction!(real y, int n) term)
 *
 * Evaluate a power series at compile time.
 *
 * Given a metafunction of the form
 *  real term!(real y, int n),
 * which gives the nth term of a convergent series at the point y
 * (where the first term is n==1), and a real number x,
 * this metafunction calculates the infinite sum at the point x
 * by adding terms until the sum doesn't change any more.
 */
template evaluateSeries(real x, alias term, int n=1, real sumsofar=0.0)
{
  static if (n>1 && sumsofar == sumsofar + term!(x, n+1)) {
     const real evaluateSeries = sumsofar;
  } else {
     const real evaluateSeries = evaluateSeries!(x, term, n+1, sumsofar + term!(x, n));
  }
}

/*** Calculate atan(x) at compile time.
 *
 * Uses the Maclaurin formula
 *  atan(z) = z - z^3/3 + Z^5/5 - Z^7/7 + ...
 */
template atan(real z)
{
    const real atan = evaluateSeries!(z, atanTerm);
}

template atanTerm(real x, int n)
{
    const real atanTerm =  (n & 1 ? 1 : -1) * pow!(x, 2*n-1)/(2*n-1);
}

/// Machin's formula for pi
/// pi/4 = 4 atan(1/5) - atan(1/239).
pragma(msg, "PI = " ~ fcvt!(4.0 * (4*atan!(1/5.0) - atan!(1/239.0))) );
0
जोड़ा
दुर्भाग्यवश, टैंगेंट आर्कटैंजेंट पीआई पर आधारित होते हैं, कुछ हद तक इस गणना को अमान्य कर देते हैं।
जोड़ा लेखक Grant Johnson, स्रोत

वास्तव में एक पूरी किताब समर्पित है (अन्य चीजों के साथ) \ pi की गणना के लिए तेज़ विधियों के लिए: 'पीआई और एजीएम', जोनाथन और पीटर बोरविन द्वारा ( अमेज़ॅन पर उपलब्ध )।

मैंने एजीएम और संबंधित एल्गोरिदम का अध्ययन काफी हद तक किया: यह काफी रोचक है (हालांकि कभी-कभी गैर-तुच्छ)।

ध्यान दें कि \ pi की गणना करने के लिए सबसे आधुनिक एल्गोरिदम लागू करने के लिए, आपको एक बहुसंख्यक अंकगणितीय पुस्तकालय की आवश्यकता होगी ( जीएमपी काफी अच्छी पसंद है , हालांकि यह थोड़ी देर के बाद से मैंने इसका इस्तेमाल किया था)।

सर्वोत्तम एल्गोरिदम की समय-जटिलता ओ (एम (एन) लॉग (एन) में है), जहां एम (एन) दो एन-बिट पूर्णांक (एम (एन) = ओ (एन) के गुणा के लिए समय-जटिलता है लॉग (एन) लॉग (लॉग (एन))) एफएफटी-आधारित एल्गोरिदम का उपयोग करते हुए, जिन्हें आमतौर पर \ pi के अंकों की गणना करते समय आवश्यक होता है, और ऐसे एल्गोरिदम जीएमपी में लागू किया जाता है)।

ध्यान दें कि भले ही एल्गोरिदम के पीछे गणित तुच्छ नहीं हो सकता है, फिर भी एल्गोरिदम आमतौर पर छद्म कोड की कुछ पंक्तियां होती हैं, और उनका कार्यान्वयन आमतौर पर बहुत सरल होता है (यदि आपने अपना स्वयं का मल्टीप्रसिजन अंकगणित :-) लिखना नहीं चुना है)।

0
जोड़ा

यह एक "क्लासिक" विधि है, जो कार्यान्वित करने में बहुत आसान है। यह क्रियान्वयन, पायथन में (इतनी तेज़ भाषा नहीं) यह करता है:

from math import pi
from time import time


precision = 10**6 # higher value -> higher precision
                  # lower  value -> higher speed

t = time()

calc = 0
for k in xrange(0, precision):
    calc += ((-1)**k) / (2*k+1.)
calc *= 4. # this is just a little optimization

t = time()-t

print "Calculated: %.40f" % calc
print "Costant pi: %.40f" % pi
print "Difference: %.40f" % abs(calc-pi)
print "Time elapsed: %s" % repr(t)

आप यहां अधिक जानकारी प्राप्त कर सकते हैं।

वैसे भी पाइथन में पीआई के सटीक के रूप में आप के रूप में मूल्यवान मूल्य प्राप्त करने का सबसे तेज़ तरीका है:

from gmpy import pi
print pi(3000) # the rule is the same as 
               # the precision on the previous code

यहां gmpy pi विधि के लिए स्रोत का टुकड़ा है, मुझे नहीं लगता कि कोड इस मामले में टिप्पणी के रूप में उतना ही उपयोगी है:

static char doc_pi[]="\
pi(n): returns pi with n bits of precision in an mpf object\n\
";

/* This function was originally from netlib, package bmp, by
 * Richard P. Brent. Paulo Cesar Pereira de Andrade converted
 * it to C and used it in his LISP interpreter.
 *
 * Original comments:
 * 
 *   sets mp pi = 3.14159... to the available precision.
 *   uses the gauss-legendre algorithm.
 *   this method requires time o(ln(t)m(t)), so it is slower
 *   than mppi if m(t) = o(t**2), but would be faster for
 *   large t if a faster multiplication algorithm were used
 *   (see comments in mpmul).
 *   for a description of the method, see - multiple-precision
 *   zero-finding and the complexity of elementary function
 *   evaluation (by r. p. brent), in analytic computational
 *   complexity (edited by j. f. traub), academic press, 1976, 151-176.
 *   rounding options not implemented, no guard digits used.
*/
static PyObject *
Pygmpy_pi(PyObject *self, PyObject *args)
{
    PympfObject *pi;
    int precision;
    mpf_t r_i2, r_i3, r_i4;
    mpf_t ix;

    ONE_ARG("pi", "i", &precision);
    if(!(pi = Pympf_new(precision))) {
        return NULL;
    }

    mpf_set_si(pi->f, 1);

    mpf_init(ix);
    mpf_set_ui(ix, 1);

    mpf_init2(r_i2, precision);

    mpf_init2(r_i3, precision);
    mpf_set_d(r_i3, 0.25);

    mpf_init2(r_i4, precision);
    mpf_set_d(r_i4, 0.5);
    mpf_sqrt(r_i4, r_i4);

    for (;;) {
        mpf_set(r_i2, pi->f);
        mpf_add(pi->f, pi->f, r_i4);
        mpf_div_ui(pi->f, pi->f, 2);
        mpf_mul(r_i4, r_i2, r_i4);
        mpf_sub(r_i2, pi->f, r_i2);
        mpf_mul(r_i2, r_i2, r_i2);
        mpf_mul(r_i2, r_i2, ix);
        mpf_sub(r_i3, r_i3, r_i2);
        mpf_sqrt(r_i4, r_i4);
        mpf_mul_ui(ix, ix, 2);
        /* Check for convergence */
        if (!(mpf_cmp_si(r_i2, 0) && 
              mpf_get_prec(r_i2) >= (unsigned)precision)) {
            mpf_mul(pi->f, pi->f, r_i4);
            mpf_div(pi->f, pi->f, r_i3);
            break;
        }
    }

    mpf_clear(ix);
    mpf_clear(r_i2);
    mpf_clear(r_i3);
    mpf_clear(r_i4);

    return (PyObject*)pi;
}

EDIT: I had some problem with cut and paste and identation, anyway you can find the source here.

0
जोड़ा

क्रिस द्वारा ऊपर पोस्ट की गई ब्रेंट की विधि बहुत अच्छी है; ब्रेंट आम तौर पर मनमाना-परिशुद्धता अंकगणित के क्षेत्र में एक विशालकाय है।

यदि आप चाहते हैं कि एनएच अंक, प्रसिद्ध है बीबीपी फॉर्मूला हेक्स में उपयोगी है

0
जोड़ा
ब्रेंट विधि मेरे द्वारा पोस्ट नहीं की गई थी; यह एंड्रिया द्वारा पोस्ट किया गया था, और मैं बस आखिरी व्यक्ति बन गया जो इस पोस्ट को संपादित करता था। :-) लेकिन मैं सहमत हूं कि पोस्ट एक अपवित्रता के हकदार है।
जोड़ा लेखक Chris Jester-Young, स्रोत

युगल के साथ:

4.0 * (4.0 * Math.Atan(0.2) - Math.Atan(1.0 / 239.0))

यह 14 दशमलव स्थानों तक सटीक होगा, जो डबल को भरने के लिए पर्याप्त है (गलतता शायद इसलिए है क्योंकि चाप टेंगेंट में शेष दशमलव को छोटा कर दिया जाता है)।

इसके अलावा सेठ, यह 3.14159265358979323846 3 है, 64 नहीं।

0
जोड़ा

Machin- जैसे सूत्र का प्रयोग करें

176 * arctan (1/57) + 28 * arctan (1/239) - 48 * arctan (1/682) + 96 * arctan(1/12943) 

[; \left( 176 \arctan \frac{1}{57} + 28 \arctan \frac{1}{239} - 48 \arctan \frac{1}{682} + 96 \arctan \frac{1}{12943}\right) ;], for you TeX the World people.

उदाहरण के लिए, योजना में कार्यान्वित:

<�कोड> (+ (- (+ (* 176 (अतान (/ 1 57)) (* 28 (अतान (/ 1 23 9))) (* 48 (अतान (/ 1 682))) (* 9 6 (एटान (/ 1 12 9 43)))) </कोड>

0
जोड़ा