2015-11-10 3 views
13
में सत्ता पर अतिप्रवाह पता लगाने के लिए

मुझे पता है कि java.lang.Math एक ArithmeticException फेंकने कुछ कार्यों (sum, difference, multiply, increment, decrement, negate, toInt) प्रदर्शन करने के लिए स्थिर तरीकों का एक सेट प्रदान अतिप्रवाह परकैसे जावा

क्या बिजली के लिए कुछ समान है?

उत्तर

9

नहीं, जावा में निर्मित pow के बराबर कुछ भी नहीं है। (केवल pow जावा में बनाया तरीकों Math.pow जो युगल स्वीकार करता है और उसी तरह पूर्णांकों कर में अतिप्रवाह नहीं करता है, और BigInteger.pow कर रहे हैं, जो अतिप्रवाह क्योंकि BigInteger रों मनमाने ढंग से बड़ा हो सकता है नहीं करता है।)

तीसरे पक्ष के पुस्तकालयों हैं स्वीकार्य हैं, हालांकि, अमरूद के उदाहरण हैं IntMath.checkedPow, जो आप खोज रहे हैं वह करता है।

+0

मुझे लगता है कि आपको 'LongMath.checkedPow' का भी उल्लेख करना चाहिए। मुझे लगता है (हालांकि मैं गलत हो सकता हूं) यह 'int' के लिए छोटा है क्योंकि प्रत्येक 'int' को डबल के रूप में प्रदर्शित किया जा सकता है, इसलिए आपको केवल' Math.pow (a, b) 'करने की आवश्यकता है और' Integer.MAX_VALUE 'की तुलना करें '। –

+0

@ लुइस यदि मैं 'BigInteger' का उपयोग करता हूं तो मैं प्राप्त संख्या के आकार के बारे में चिंता नहीं कर सकता? – Claudia

+1

@ क्लाउडिया [बिगइंटर] (https://docs.oracle.com/javase/8/docs/api/java/math/BigInteger.html): "मनमानी-परिशुद्धता पूर्णांक ... संबंधित स्पेक में सभी विवरण ओवरफ्लो को नजरअंदाज कर दिया जाता है, क्योंकि बिगइंटर को ऑपरेशन के परिणामों को समायोजित करने के लिए जितना आवश्यक हो उतना बड़ा बनाया जाता है। " –

0

इंटीग्रर्स केवल 32 बिट हैं। तो अधिकतम मूल्य 2^31 -1 है। (BigInteger.pow का उपयोग कर रहा है। यह कम कुशल है।) तो यदि आप आवश्यक हैं तो आप मैन्युअल रूप से जांच सकते हैं और अपवाद फेंक सकते हैं और Math.pow का उपयोग करें जो डबल का उपयोग करता है।

+3

यह कोई जवाब नहीं है। सवाल यह है कि क्या ऐसी कोई विधि है (मुझे जावा 8 एपीआई के भीतर लगता है)। – Turing85

+0

जो मैं कहने की कोशिश कर रहा हूं वह यह है कि हम अपना कोड लिख सकते हैं और अपवाद में कोई निर्माण नहीं है। धन्यवाद। – Chirag

+0

जावा ट्यूरिंग-पूर्ण है, इसलिए यह माना जाता है कि आप जावा के भीतर कोई भी एल्गोरिदम लिख सकते हैं। – Turing85

4

Chirag ने कहा, पूर्णांक जब अपवाद करते हैं तो अपवाद फेंकते हैं। बहुत विशिष्ट नहीं होना चाहिए, लेकिन मूल रूप से, स्मृति में युगल वैज्ञानिक नोटेशन के समान ही संग्रहीत होते हैं, जिसमें वे कुछ पूर्णांक * 2^(कुछ शक्ति) होते हैं, और इस तरह वास्तव में कभी भी बहती नहीं है लेकिन इतनी बड़ी या छोटी 2^(कुछ शक्ति) कि वे पूरी तरह से अपनी परिशुद्धता खो देते हैं। तो आप इसके बजाय डबल ओवरफ्लो के बारे में सोच सकते हैं क्योंकि जब वे पूरी तरह से अपनी सटीकता खो देते हैं और Infinity या -Infinity के रूप में मुद्रित होते हैं।

तो, आपको मैन्युअल रूप से जांचना होगा कि परिणामी मान Double.POSITIVE_INFINITY या Double.NEGATIVE_INFINITY है या नहीं, यह जांच कर एक ओवरफ़्लो हुआ है।

public static void main(String[] args) throws Exception 
{ 
    double a = Double.MAX_VALUE; // highest possible double 
    double b = Double.MAX_VALUE; // highest possible double 

    if (Math.pow(a, b) == Double.POSITIVE_INFINITY || Math.pow(a, b) == Double.NEGATIVE_INFINITY) 
    { 
     throw new ArithmeticException("Double Overflow"); 
    } 
} 
1

अगर यह अपने खुद के कार्यान्वयन के लिए ठीक है, आप कुछ इस तरह कर सकता है::

private static final int[] maxBaseForExponent = IntStream.range(0, 30) 
     .map(e -> (int) Math.pow(Integer.MAX_VALUE, 1d/e)).toArray(); 

public static int powExact(int base, int exponent) { 
    if (exponent < 0) { 
     throw new ArithmeticException("Negative exponent"); 
    } 
    if ((base < -1 || base > 1) && (exponent > 30 || base > maxBaseForExponent[exponent]) 
      && !(base == -2 && exponent == 31)) { 
     throw new ArithmeticException("Overflow"); 
    } 
    switch (base) { 
    case -2: 
     return (exponent & 1) == 0 ? 1 << exponent : -1 << exponent; 
    case -1: 
     return (exponent & 1) == 0 ? 1 : -1; 
    case 0: 
     return exponent == 0 ? 1 : 0; 
    case 1: 
     return 1; 
    case 2: 
     return 1 << exponent; 
    default: 
    } 
    int result = 1; 
    while (exponent != 0) { 
     if ((exponent & 1) != 0) { 
      result *= base; 
     } 
     exponent >>= 1; 
     base *= base; 
    } 
    return result; 
} 

here से एल्गोरिथ्म लिया

यहाँ दिखाने के लिए मैं क्या मतलब है कुछ नमूना कोड है , और इसे एक सरणी का उपयोग करके अतिप्रवाह की जांच करने के लिए संशोधित किया गया है जिसमें 0 से 30 तक प्रत्येक एक्सपोनेंट के लिए अधिकतम आधार होता है।