php - Fast arbitrary-precision logarithms with bcmath -
यहां मुझे जो मिला है
function bcln ($ n, $ scale = 10 ) {$ Iscale = $ scale + 3; $ परिणाम = '0.0'; $ I = 0; करो {$ pow = (1 + (2 * $ i ++)); $ Mul = bcdiv ('1', $ pow, $ iscale); $ Fraction = bcmul ($ mul, bcpow (bcsub ($ n, '1', $ iscale) / bcadd ($ n, '1.0', $ iscale), $ pow, $ iscale), $ iscale; $ अंतिम परिणाम = $ परिणाम; $ परिणाम = बीकैड ($ अंश, $ परिणाम, $ iscale); } जबकि ($ परिणाम! == $ अंतिम परिणाम); वापसी बीसीएमयूएल ('2', $ परिणाम, $ स्केल); } लेकिन यह bcln (100) (100, 10 दशमलव स्थानों का प्राकृतिक लॉग) चलाने के लिए 5.7 सेकंड लगते हैं। इसके अलावा, यह अधिक दशमलव स्थानों के लिए हमेशा सटीक नहीं होता है क्या कोई बेहतर एल्गोरिदम है? उस विशिष्ट चलाने के लिए, 573 पुनरावृत्तियों को परिणाम पर व्यवस्थित करने के लिए लेता है।
क्या आपको उत्तर के रूप में एक मनमाना-लंबाई वाली स्ट्रिंग की आवश्यकता है? या क्या आपको मनमाना सटीक, या मनमाना एक्सपोनेंट आकार की आवश्यकता है? ओआरए ?? | एक डबल-सटीक फ़्लोटिंग-पॉइंट उत्तर (रिटर्न-वैल्यू) पर्याप्त होगा; यह देखते हुए कि हम "केवल" " मनमाने ढंग से " आकार के लॉगरिदम के साथ "केवल" काम कर रहे हैं? डबल परिशुद्धता फ़्लोटिंग बिंदु संख्या में एक 11 -बीटी हस्ताक्षर प्रतिपादक: इसलिए, यदि आपकी बड़ी संख्या स्ट्रिंग की लंबाई है ?? ¤1022 बिट्स 307 दशमलव अंक (दशमलव की दशमलव सहित 306 अक्षरों की स्ट्रिंग लंबाई), आप सुरक्षित हैं! अधिक सटीक रूप से, आपको सुरक्षित होना चाहिए, यदि परिणामस्वरूप दशमलव व्युत्पन्न का पूर्ण मूल्य होता है ?? ¤307 क्या आपको उस की तुलना में बड़ा एक्सपोनेंट चाहिए? (मुझे लगता है कि दूसरे शब्दों में: क्या आप वास्तविक दुनिया संख्याओं या सैद्धांतिक / शुद्ध गणित के साथ काम कर रहे हैं?)
क्यों कुछ स्ट्रिंग प्रसंस्करण का उपयोग ही कुछ सरल अस्थायी-बिंदु लॉग अंकगणितीय के साथ नहीं? यह किसी भी वास्तविक दुनिया संख्याओं के लिए बहुत तेज़ होना चाहिए .? | फ़ंक्शन bclog10 ($ n) {// â "???? लागू करने की आवश्यकता हो सकती है यहाँ कुछ सत्यापन तर्क! $ स्थिति = strpos ($ एन, '।'); अगर ($ pos === गलत) {$ dec_frac = '।'। Substr ($ n, 0,15); $ pos = strlen ($ n); } और {$ dec_frac = '।'। Substr (substr ($ n, 0, $ pos) .substr ($ n, $ pos + 1), 0,15); } वापसी लॉग 10 ((फ्लोट) $ dec_frac) + (फ़्लोट) $ pos; } आप कुछ प्रसिद्ध ज्ञात लॉग अंकगणितीय का उपयोग कर कनवर्ट कर सकते हैं:
फ़ंक्शन bclogn ($ n, $ base = M_E) {// $ आधार फ्लोट होना चाहिए: डिफ़ॉल्ट ई रिटर्न bclog10 ($ n) * लॉग (10) / लॉग ($ बेस); } मैंने इन फ़ंक्शनों का परीक्षण किया है और वे मेरे लिए दिए गए उदाहरणों के लिए काम करते हैं; पीएसए द्वारा इस्तेमाल किए जाने वाले दोहरे परिशुद्धता अंकगणित की सीमा तक, विंडोज 10 कैलकुलेटर के समान ही जवाब देने के साथ।
यदि आपको वास्तव में 15 अंकों की सटीकता की आवश्यकता है और 307 से अधिक दशमलव एक्सपोनेंट , आप अपने "बिग फ्लेट" वर्ग के ऑब्जेक्ट को लागू करने में सक्षम हो सकते हैं, और किसी भी तरह से अपने तरीके को एक विभाजित-और-विजय दृष्टिकोण का उपयोग करते हुए मानक निर्मित फ्लोटिंग-बिंदु फ़ंक्शंस से बना सकते हैं! तो शायद, हम इसका उपयोग एक मनमाना-सटीक फ़्लोटिंग-पॉइंट लॉगरिथ्म एल्गोरिथ्म के आधार के रूप में कर सकते हैं, ऊपर वर्णित कार्यों / तकनीकों के साथ संयोजन के द्वारा। आप लोगों के साथ परामर्श करने पर विचार करना चाह सकते हैं, यह जानने के लिए कि यह एक व्यावहारिक दृष्टिकोण हो सकता है या नहीं।
मुख्य संपादन: 2 प्रयास ?? | फ़ंक्शन bclog10 ($ n) {// मैथ्यू सलीमन @ aaabit.com $ m = सरणी (); // ??? मान्यकरण, मिलान / प्रोसेसिंग रेगेक्स ?? | प्रीग_मैच ('/ ^ (-) * 0 * ([1- 9] [0-9] *)? ((। (0 *))? ([1- 9] [ 0-9] *) ([ई] (-) 0 * ([1-9] [0-9] *)) $ / ', $ एन, $ एम)?; If (! Isset ($ m [1])) {नया एक्सप्शन ('तर्क: दशमलव संख्या स्ट्रिंग नहीं!');} $ Sgn = $ m [1]; यदि ($ sgn === '-') {नए निष्कर्ष निकालना ('गणना नहीं कर सकते: लॉग (& lt; â ?? º0)!');} $ Abs = $ m [2]; $ pos = strlen ($ abs); अगर (isset ($ मी [4])) {$ fre = $ मीटर [4];} else {$ fre = '';} $ neg = strlen ($ fre); अगर (isset ($ m [5])) {$ frc = $ m [5];} और {$ frc = '';} अगर (isset ($ m [7])) $ $ esgn = $ m [7 ] === '-'? - 1: 1;} और {$ esgn = 1;} अगर (isset ($ m [8])) {$ eexp = $ m [8];} और {$ eexp = 0 ;} अगर ($ pos === 0) {$ dec_frac = '।'। Substr ($ frc, 0, 15); $ pos = -1 * $ neg; } और {$ dec_frac = '।'। Substr ($ abs। $ Fre। $ Frc, 0, 15); } वापसी लॉग 10 (फ्लोट) $ dec_frac) + (फ़्लोट) $ pos + ($ esgn * $ eexp); }
Comments
Post a Comment