2009-09-26 6 views
5

के साथ ई का बेहतर अनुमान I किसी भी वांछित परिशुद्धता के लिए ई के मान का अनुमान लगाना चाहता हूं। इसे करने का बेहतरीन तरीका क्या है? सबसे अधिक मैं प्राप्त करने में सक्षम हूं ई = 2.7182818284590455 है। निम्नलिखित कोड के संशोधन पर किसी भी उदाहरण की सराहना की जाएगी।जावा

public static long fact(int x){ 
    long prod = 1; 
    for(int i = 1; i <= x; i++) 
     prod = prod * i; 
    return prod; 
}//fact 

public static void main(String[] args) { 
    double e = 1; 
    for(int i = 1; i < 50; i++) 
     e = e + 1/(double)(fact(i)); 
    System.out.print("e = " + e); 
}//main 
+5

स्पष्ट रूप से एक डबल में इसकी सटीकता से अधिक अंक कभी नहीं हो सकते हैं। एक अलग प्रकार की संख्या का प्रयोग करें। – Joren

+2

जोरेन ने कहा कि बहुत कुछ। "किसी भी वांछित परिशुद्धता" का विचार मौलिक रूप से एक निश्चित चौड़ाई प्रकार में गणना के साथ असंगत है। –

उत्तर

13

डबल के बजाय BigDecimal का उपयोग करें।

BigDecimal e = BigDecimal.ONE; 
BigDecimal fact = BigDecimal.ONE; 

for(int i=1;i<100;i++) { 
    fact = fact.multiply(new BigDecimal(i)); 

    e = e.add(BigDecimal.ONE.divide(fact, new MathContext(10000, RoundingMode.HALF_UP))); 
} 
+0

इसे कार्यान्वित करने पर रनटाइम पर दिया गया: थ्रेड में मुख्य "java.lang.ArithmeticException: गैर-समाप्ति दशमलव विस्तार; कोई सटीक प्रतिनिधित्व करने योग्य दशमलव परिणाम नहीं। क्या कुछ याद आ रही है? – Sharon

+0

क्षमा करें। डिवीजन को एक RoundingMode की आवश्यकता है, अन्यथा 1/3 देखकर BigDecimal फेंकता है। ठीक कर दिया। – Zed

+0

मैं इसका उपयोग कैसे करूं? मैं लूप के बाद System.out.println (ई) करता हूं और 3 – flybywire

3

यदि आप 4 से 49 के बजाय 49 से 1 तक की गिनती करते हैं तो आपको बेहतर परिणाम मिलेंगे।

6

आपकी मुख्य समस्या यह है कि double बहुत सीमित है। यदि आप मनमाना परिशुद्धता चाहते हैं, तो आपको BigDecimal का उपयोग करना होगा। अगली समस्या जिसे आप चलाने जा रहे हैं long की सीमित सीमा है जिसे आप फैक्टोरियल के साथ बहुत तेज़ी से पार करने जा रहे हैं - वहां आप BigInteger का उपयोग कर सकते हैं।

4

क्या आपने java.util.BigDecimal में मनमाने ढंग से सटीक अंकगणित पर एक नज़र डाली है?

import java.math.BigDecimal; 
import java.math.MathContext; 
public class BigExp { 
    public static void main(String[] args) { 
BigDecimal FIFTY =new BigDecimal("50"); 
BigDecimal e = BigDecimal.ZERO; 
BigDecimal f = BigDecimal.ONE; 
MathContext context = new MathContext(1000); 

for (BigDecimal i=BigDecimal.ONE; i.compareTo(FIFTY)<0; i=i.add(BigDecimal.ONE)) { 
    f = f.multiply(i, context); 
    e = e.add(i.divide(f,context),context); 

    System.out.println("e = " + e); 
} 
    } 
} 
+0

यह मेरे लिए काम करता है, लेकिन जेड का जवाब (स्वीकृत) – flybywire

0

को समझने के लिए तुम क्यों double साथ नहीं मिल सकता है "किसी भी वांछित परिशुद्धता", इस क्लासिक कागज पढ़ें:

What Every Computer Scientist Should Know About Floating-Point Arithmetic

ध्यान दें कि है कि एक काफी तकनीकी पत्र है। फ़्लोटिंग-पॉइंट नंबरों के काम के बारे में अधिक बुनियादी जानकारी के लिए, यह विकिपीडिया आलेख देखें: Double precision floating-point format

1

ज़ेड और mobrule कोड के भिन्नता के साथ गया। महान काम करता है, धन्यवाद! अधिक प्रदर्शन सलाह किसी को भी?

public static BigDecimal factorial(int x){ 
    BigDecimal prod = new BigDecimal("1"); 
    for(int i = x; i > 1; i--) 
     prod = prod.multiply(new BigDecimal(i)); 
    return prod; 
}//fact 

public static void main(String[] args) { 
    MathContext mc = new MathContext(1000); 
    BigDecimal e = new BigDecimal("1", mc); 
    for(int i = 1; i < 1000; i++) 
     e = e.add(BigDecimal.ONE.divide(factorial(i), mc)); 
    System.out.print("e = " + e); 
}//main 
+0

प्रदर्शन सलाह नहीं है: फैक्टोरियल को फिर से शुरू करना बंद करें। ज़ेड के समाधान का प्रयोग करें जहां आप "तथ्य = तथ्य। Multiply (नया BigDecimal (i))" लूप में, इसे फिर से गणना करने के बजाय करते हैं। –

+0

एक सबूत के रूप में, mobrule का समाधान 542ms में चलता है, आपका संस्करण 1000 पुनरावृत्तियों के लिए 858ms में चलता है। –

1

अधिक प्रदर्शन सलाह किसी को भी?

हां, फैक्टरियल की आपकी गणना उतनी ही अक्षम है जितनी इसे प्राप्त होती है। उस लूप के अंदर स्थानांतरित करना बेहतर होगा जहां आप शर्तों को जोड़ रहे हैं। जिस तरह से आप चीजें कर रहे हैं ओ ओ (एन) समस्या को ओ (एन^2) समस्या में बदल देता है।

और यदि यह एक असली गणना थी जिसे कारखानों की आवश्यकता होती है, तो मैं एक टेबल लुकअप या अपूर्ण गामा फ़ंक्शन को करने का सही तरीका सुझाता हूं।

एकमात्र चीज जिसे आप प्रदर्शन बिंदु से खराब कर सकते थे, एक पुनरावर्ती फैक्टरियल गणना है। फिर आपको एक विशाल ढेर की अतिरिक्त समस्या होगी।