2012-02-13 16 views
6

के साथ लटकता है निम्न प्रोग्राम फ्रीज करता है, और मैं क्यों काम नहीं कर सकता।BigDecimal.movePointRight() बहुत बड़ी संख्या

import java.math.*; 

public class BigDec { 
    public static BigDecimal exp(double z) { 
     // Find e^z = e^intPart * e^fracPart. 
     return new BigDecimal(Math.E).pow((int)z, MathContext.DECIMAL128). 
      multiply(new BigDecimal(Math.exp(z-(int)z)), MathContext.DECIMAL128); 
    } 

    public static void main(String[] args) { 
     // This works OK: 
     BigDecimal x = new BigDecimal(3E200); 
     System.out.println("x=" + x); 
     System.out.println("x.movePointRight(1)=" + x.movePointRight(1)); 

     // This does not: 
     x = exp(123456789); 
     System.out.println("x=" + x); 
     System.out.println("x.movePointRight(1)=" + x.movePointRight(1)); //hangs 
    } 
} 

वर्तमान उद्देश्यों के लिए, पहली विधि सिर्फ एक बहुत बड़ी बिगडिसीमल बनाती है। (विवरण: यह ज़ेड की शक्ति के लिए ई पाता है, भले ही यह बहुत बड़ा हो। मुझे पूरा यकीन है कि यह विधि सही है, हालांकि मैथकॉन्टेक्स सबसे अच्छे स्थानों में नहीं हो सकता है।)

मुझे पता है ई^123456789 बेहद बड़ा है, लेकिन मैं वास्तव में इस तरह की संख्या का उपयोग करना चाहता हूं। किसी भी उत्तर बहुत आभारी रूप से प्राप्त किया जाएगा।

उत्तर

4

वास्तव में यह स्थिर नहीं होता है, लेकिन ओरेकल के वीएम में movePointRight का कार्यान्वयन बेहद अक्षम हो सकता है। movePointRight या movePointLeft विधियों का उपयोग करने के बजाय 10 की शक्ति के साथ गुणा या विभाजित करना अक्सर तेज़ होता है। आपके मामले में, x.multiply(BigDecimal.TEN) का उपयोग शायद अधिक बेहतर काम करेगा।

+0

धन्यवाद। यह दृढ़ लगता है, और 'x.multiply (BigDecimal.TEN)' ठीक काम करता है। मैंने सप्ताहांत (दुर्घटना से) पर अपना कार्यक्रम छोड़ा, और यह अभी भी सोमवार की सुबह समाप्त नहीं हुआ था, इसलिए 'movePointRight' केवल अत्यंत ही अविश्वसनीय रूप से अक्षम नहीं होना चाहिए। इसे बस इतना करना है कि बिगडेसिमल के "स्केल" को 1 से बदल दें, इसलिए यह काफी परेशान है। –

+0

मैंने पूरे कार्यान्वयन की जांच नहीं की है, लेकिन किसी बिंदु पर, movePointXYZ 10 के क्रम में (बिगडिसीमल में अंकों की संख्या) के क्रम में एक मध्यवर्ती बिगइंटर उदाहरण बनाता है। यह एक अग्रणी '1' के साथ एक स्ट्रिंग (वास्तव में एक char []) बनाता है, इसके बाद 53 मिलियन '0' वर्ण होते हैं और इसे बिगइंटर कन्स्ट्रक्टर में पास करते हैं। BigInteger कार्यान्वयन तब आंतरिक संख्या सरणी में 32 बिट भाग में एन्कोड किए गए इस संख्या बाइनरी को पैक करने का प्रयास करता है और यह वास्तविक अपराधी है। – jarnbjo

संबंधित मुद्दे