मैं bcmath
विस्तार के लिए एक आवरण लिख रहा हूँ, और bug #10116bcpow()
के बारे में विशेष रूप से परेशान है - यह $right_operand
($exp
) एक (देशी पीएचपी करने के लिए, नहीं मनमाने ढंग से लंबाई डाले) पूर्णांक, इसलिए जब आप किसी संख्या के वर्ग रूट (या 1
से अधिक किसी अन्य रूट की गणना करने का प्रयास करते हैं) तो आप हमेशा सही परिणाम के बजाय 1
के साथ समाप्त होते हैं।गिना जा रहा है फ्लोटिंग प्वाइंट शक्तियों (PHP/BCMath)
मैं एल्गोरिदम है कि मुझे एक नंबर के n वीं मूल और मैं found this answer जो बहुत ठोस लग रहा है की गणना करने की अनुमति होगी के लिए खोज शुरू कर दिया, मैं वास्तव में expanded the formula का उपयोग कर वॉलफ्रेम अल्फा और मैं जबकि सटीकता रखने के बारे में 5% से यह गति है में सुधार करने में सक्षम था परिणाम के।
यहाँ एक शुद्ध पीएचपी मेरी BCMath कार्यान्वयन और अपनी सीमाएं नकल उतार दिया गया है:
function _pow($n, $exp)
{
$result = pow($n, intval($exp)); // bcmath casts $exp to (int)
if (fmod($exp, 1) > 0) // does $exp have a fracional part higher than 0?
{
$exp = 1/fmod($exp, 1); // convert the modulo into a root (2.5 -> 1/0.5 = 2)
$x = 1;
$y = (($n * _pow($x, 1 - $exp))/$exp) - ($x/$exp) + $x;
do
{
$x = $y;
$y = (($n * _pow($x, 1 - $exp))/$exp) - ($x/$exp) + $x;
} while ($x > $y);
return $result * $x; // 4^2.5 = 4^2 * 4^0.5 = 16 * 2 = 32
}
return $result;
}
ऊपर seems to work greatको छोड़कर जब 1/fmod($exp, 1)
एक पूर्णांक उपज नहीं है। उदाहरण के लिए, यदि $exp
0.123456
है, इसका उलटा 8.10005
और pow()
और _pow()
के परिणाम होगा कुछ अलग (demo) हो जाएगा:
pow(2, 0.123456)
=1.0893412745953
_pow(2, 0.123456)
=1.0905077326653
_pow(2, 1/8)
=_pow(2, 0.125)
=1.0905077326653
"मैनुअल" घातीय गणनाओं का उपयोग करके मैं समान स्तर की सटीकता कैसे प्राप्त कर सकता हूं?
यह बिल्कुल के रूप में विज्ञापित काम कर रहा है उपयोग करने के लिए है। निकटतम '1/n' के लिए आंशिक भाग '_pow'' राउंड '। आप इस काम को बार-बार कर सकते हैं। तो '_pow (2, 0.125)' की गणना करने के बाद, आप '_pow (2,0.125-123456) 'की गणना करते हैं और इसी तरह। –
आह, अब मैं समझता हूं। तो bcmath में 'exp' और' log' नहीं है या अन्य कारण हैं कि 'a^b = exp (b * log (a)) 'कोई विकल्प नहीं है? रिकर्सन जेफरी का सुझाव है कि निश्चित रूप से काम करेगा, लेकिन अगर आपको एक्सपोनेंट का प्रतिनिधित्व करने के लिए कई '1/के' की ज़रूरत है तो इसकी गति संतोषजनक नहीं हो सकती है। एक्सपोनेंट को तर्कसंगत संख्या 'एन/डी' के रूप में लिख रहा है और' (ए^एन)^(1/डी) 'एक विकल्प की गणना कर रहा है, या बहुत बड़ी' n' और 'd' की अपेक्षा की जानी चाहिए? शायद एक जांच के लायक एक तर्कसंगत संख्या द्वारा एक्सपोनेंट को अनुमानित कर रहा है जिसमें छोटे डिमॉमिनेटर (निरंतर अंश विस्तार) और बाकी के साथ रिकर्सन किया जा रहा है। –
@ जेफरी सैक्स: आह, मैं देखता हूं ... यह एक बमर है लेकिन अभी भी काम नहीं कर रहा है (http://codepad.org/eI4ykyQU) या क्या मुझे कुछ याद आ रही है? –