java - Logarithm for BigInteger -
मेरे पास BigInteger
नंबर है, उदाहरण के लिए 2 64 से परे अब मैं उस BigInteger
संख्या के लॉगरिथम की गणना करना चाहता हूं, लेकिन विधि BigInteger.log ()
मौजूद नहीं है मैं अपने बड़े BigInteger
मान के (प्राकृतिक) लघुगणक की गणना कैसे करूं?
<पी > यदि आप मनमाने ढंग से बड़े पूर्णांकों का समर्थन करना चाहते हैं, तो बस इसे करना सुरक्षित नहीं है
Math.log (bigInteger.doubleValue ());
क्योंकि यह तर्क यदि डबल
सीमा (लगभग 2 ^ 1024 या 10 ^ 308, अर्थात 300 से अधिक दशमलव अंक) से अधिक है, तो विफल हो जाएगा।
यह मेरा नुस्खा है:
<पूर्व> निजी स्थिर अंतिम डबल LOG2 = Math.log (2.0); / ** * बिगइंटेगर के प्राकृतिक लॉगरिदम का मूल्यांकन करता है वास्तव में बड़े * पूर्णांक (व्यावहारिक रूप से असीमित) के लिए काम करता है * * @ परम वैल तर्क, सकारात्मक पूर्णांक * @ परत से प्राकृतिक लघुगणक, जैसे & gt; Math.log () & lt; / tt & gt; * / सार्वजनिक स्थिर डबल लॉगबिगइन्टेगर (बिगइटेगर वैल) {इंट बॉक्ले = वैलबाइट लैंग () - 1022; // 60..1023 में कोई भी मान ठीक है अगर (ब्लेक्स & gt; 0) val = val.shiftRight (blex); डबल res = Math.log (val.doubleValue ()); वापसी बैक्स & gt; 0? Res + blex * LOG2: res; }
मैंने वास्तव में बड़ी बिगइटेगर (500000 से अधिक दशमलव अंकों) के साथ इसका परीक्षण किया है, और अधिकतम रिश्तेदार त्रुटि हमेशा 5.0e-16 के नीचे रही है, जो कि दोहरी
सटीक।
कुछ नमूना कोड, यदि आप स्वयं का परीक्षण करना चाहते हैं:
सार्वजनिक स्थिर दोहरी testLogBigInteger (int [ ] कारक, इंट [] एक्सपोनेंट्स) {डबल एल 1 = 0; बिगइन्टेजर बाय = बिगइंटेगर.ऑन; के लिए (int i = 0; i & lt; कारक। लम्बाई; i ++) {int exponent = exponents [i]; इंट कारक = कारक [आई]; अगर (कारक और एलटी; = 1) जारी रहता है; के लिए (int n = 0; n & lt; एक्सपोनेंट; n ++) {बाई = बाय। मल्टीप्ली (बिगइंटेर.वल्यूओफ़ (फैक्टर)); } L1 + = Math.log (कारक) * एक्सपोनेंट; } डबल एल 2 = लॉगबीगइंटेगर (बीआई); डबल त्रुटि = मठ। बाक्स ((एल 2 - एल 1) / एल 1); इंट decdigits = (int) (l1 / Math.log (10) + 0.5); System.out.printf ("e =% e digitss =% d \ n", गलती, decdigits); वापसी गलती; } सार्वजनिक स्थिर शून्य testManyTries (int की कोशिश करता है) {int [] f = {1, 1, 1, 1, 1}; Int [] ई = {1, 1, 1, 1, 1}; यादृच्छिक आर = नया रैंडम (); डबल मैकेर्र = 0; के लिए (int n = 0; n & lt; tries; n ++) {for (int i = 0; i & lt; f.length; i ++) {एफ [i] = r.nextInt (100000) + 2; ई [i] = आर। एनएक्सआईटीआईएनटी (1000) + 1; } डबल त्रुटि = testLogBigInteger (f, e); If (err & gt; maxerr) maxerr = err; } System.out.printf ("अधिकतम त्रुटि:% ई \ n", मैक्सियर); }
अद्यतन: पूर्णता के लिए, और क्योंकि मुझे इसकी आवश्यकता है, यहां एक व्युत्क्रम फ़ंक्शन है:
/ ** * गणित के समान । EXP () लेकिन एक BigInteger देता है बड़ी संख्या के लिए ओरिएंटेड। * डबल रेंज से अधिक होने वाले आउटपुट के लिए भी काम करता है * * @ परम बी एक बड़ा पॉजिटिव मान होना चाहिए * @ रिटर्न ई (प्राकृतिक लॉगरिदम के आधार) का मान पावर बी * / सार्वजनिक स्टेटिक बिगइन्टेगर बिगएक्सपी (डबल बी) {If (Double.isNaN (b) || Double.isInfinite (b)) नया अवैध अभिलेख स्थापित करना अपवाद ("अनंत या नकारात्मक मान स्वीकार नहीं किए गए:" + b); // ई ^ बी = ई ^ (बी 2 + सी) = ई ^ बी 2 2 ^ टी के साथ ई ^ सी = 2 ^ टी डबल बीसी = 680.0; If (b & lt; bc) BigDecimal.valueOf (Math.exp (b)) रिटर्न करें। SetScale (0, BigDecimal.ROUND_HALF_EVEN) .toBigInteger (); डबल बी 2 = बीसी; डबल सी = बी - बीसी; Int t = (int) Math.ceil (c / LOG2); सी = टी * LOG2; बी 2 = बी - सी; BigInteger v = BigDecimal.valueOf (मठ। एक्सप (बी 2)) setScale (0, BigDecimal.ROUND_HALF_EVEN) .toBigInteger (); वापसी v.shiftLeft (टी); } सार्वजनिक स्थिर BigInteger bigpow (डबल एक, डबल ख) {वापसी bigexp (बी * Math.log (ए)); }
Comments
Post a Comment