2012-09-10 12 views
5

मुझे पता लगाने में समस्याएं आ रही हैं कि दो संख्याओं का योग/गुणा एक लंबे पूर्णांक के अधिकतम मूल्य से अधिक है या नहीं।
उदाहरण कोड:जावा नंबर लंबा है। Max_value - कैसे पता लगाने के लिए?

long a = 2 * Long.MAX_VALUE; 
System.out.println("long.max * smth > long.max... or is it? a=" + a); 

यह मैं -2 देता है, जबकि मैं इसे फेंक की उम्मीद करेंगे एक NumberFormatException ...

वहाँ इस काम बनाने का एक आसान तरीका है? क्योंकि मेरे पास कुछ कोड है जो लूप में नेस्टेड आईएफ ब्लॉक या जोड़ों में गुणा करता है और मैं प्रत्येक IF या लूप के अंदर और अधिक IF जोड़ने से नफरत करता हूं।

संपादित करें: इस तरह से बहुत है https://stackoverflow.com/a/9057367/540394
मैं नहीं चाहता कि मुक्केबाजी/unboxing क्या करना चाहते हैं के रूप में यह unnecassary भूमि के ऊपर जोड़ता है, और: ओह ठीक है, ऐसा लगता है कि एक और सवाल से इस उत्तर के लिए सबसे उपयुक्त है कि मैं क्या जरूरत है छोटा, जो मेरे लिए एक बड़ा प्लस है। मैं इन चेकों को करने के लिए केवल दो छोटे कार्यों को लिखूंगा और न्यूनतम या अधिकतम लंबा लौटा दूंगा।

EDIT2:

/** 
* @param a : one of the two numbers added/multiplied 
* @param b : the other of the two numbers 
* @param c : the result of the addition/multiplication 
* @return the minimum or maximum value of a long integer if addition/multiplication of a and b is less than Long.MIN_VALUE or more than Long.MAX_VALUE 
*/ 
public static long limitLong(long a, long b, long c) 
{ 
    return (((a > 0) && (b > 0) && (c <= 0)) 
     ? Long.MAX_VALUE 
     : (((a < 0) && (b < 0) && (c >= 0)) ? Long.MIN_VALUE : c)); 
} 

मुझे बताओ अगर आपको लगता है यह गलत है: यहाँ जवाब मैं ऊपर से जुड़ा हुआ के अनुसार अपने न्यूनतम/अधिकतम मूल्य के लिए एक लंबे सीमित करने के लिए सुविधा नहीं होती।

+0

+1। कुछ पुस्तकालय होना चाहिए जो पूर्णांक अतिप्रवाह पहचान के लिए अनुमति देता है। – Thilo

+0

या विशेष ब्लॉक (आखिरकार कुछ ऐसा?) जो डेवलपर्स को सभी गणित कोड के लिए त्रुटि-पर-ओवरफ्लो व्यवहार सक्षम करने में सहायता कर सकता है जो मुझे अंदर आता है। मेरा मानना ​​है कि सी # में एक है। संपादित करें: इसे मिला, [सी # में चेक और अनचेक ब्लॉक] (http://msdn.microsoft.com/en-us/library/a569z7k8.aspx)। –

+0

खैर, सी # अतिप्रवाह पर त्रुटियों को फेंकने लगता है (जो मैं चुप्पी और गलत परिणामों पर बहुत अधिक पसंद करता हूं जो मुझे समझ में नहीं आता है) ... – jurchiks

उत्तर

4

यदि आप सुनिश्चित नहीं कर सकते हैं कि परिणाम 9 ट्रिलियन ट्रिलियन से कम होगा, तो मैं double या BigInteger का उपयोग करूँगा त्रुटि प्राप्त करने से आपको बहुत मदद नहीं मिलती है क्योंकि आपको अभी भी यह जानने की आवश्यकता है कि आपको क्या करना है।

अधिक बेहतर है कि आपको यह सुनिश्चित करने के लिए अपने इनपुट को सत्यापित करके पहली जगह में कोई त्रुटि नहीं मिलती है कि वे सीमा में हैं और यदि परिणाम की सीमा long से अधिक है, तो इस प्रकार का उपयोग कर सकते हैं। का उपयोग करते हुए लंबे समय के बजाय double परिशुद्धता के कुछ नुकसान कर सकते हैं:

BigInteger साथ

आप

BigInteger a = BigInteger.valueOf(2).multiply(BigInteger.valueOf(Long.MAX_VALUE)); 
long l = a.longValue(); 
if (a.compareTo(BigInteger.valueOf(l)) == 0) { 
    // ok 
} else { 
    // error 
} 
दोगुना आप कर सकते हैं

double d = 2.0 * Long.MAX_VALUE; 
long l = (long) Math.max(Long.MIN_VALUE, Math.min(Long.MAX_VALUE, d)); 
// or as a helper method. 
long l = boundedCast(d); 

नोट के साथ

कर सकते हैं।

मैं पहली जगह में त्रुटि ब्लॉक की आवश्यकता से बचना पसंद करूंगा।

+1

के रूप में समीक्षा के लिए चिह्नित किया गया था, बात यह है कि, इसे इसे 'लंबा' करने के लिए इसे कम करने की आवश्यकता है यदि यह इससे अधिक हो। शायद यह मदद करता है? एक त्रुटि प्राप्त करने से मेरे मामले में बहुत मदद मिलेगी; मैं बस पूरे कोड को एक कोशिश/पकड़ ब्लॉक में डाल सकता हूं और यदि कोई त्रुटि फेंक दी जाती है, तो मान को Long.MAX_VALUE पर सेट करें, क्योंकि मुझे इसकी आवश्यकता है। – jurchiks

+0

यदि यह लंबे समय से अधिक है, तो आप इसे ट्रिम नहीं कर सकते हैं। सबसे अच्छा आप इसे कर सकते हैं 'Long.MAX_VALUE' जो एक अच्छा समाधान नहीं है। –

+3

@ पीटर Lawrey मुझे लगता है कि इसे 'Long.MAX_VALUE' पर कैप करना है जिसका मतलब है ओपी * इसे' लंबा '* तक ट्रिम करें। – brimborium

2

लंबे समय के अधिकतम मूल्य से पहले अपवाद फेंक नहीं देता है, इसके बजाय यह वापस कण करता है। आप ऐसा करते हैं:

Long.MAX_VALUE + 1

आप देखेंगे कि परिणाम Long.MIN_VALUE के बराबर है।

आप अगर यह अधिकतम मूल्य पर पहुंच गया यह एक अपवाद की जांच फेंक और अपवाद फेंक चाहते हैं

[संपादित करें]

तुम भी यदि कोई अतिप्रवाह है की जाँच करने के Guava लाइब्रेरी का उपयोग कर सकते हैं जब आप योग दो लम्बाई;

long c = LongMath.checkedAdd(a, b); 

यह दो अपवादों के दौरान एक ओवरफ्लो होता है जब यह अपवाद फेंकता है।

आप जावाडोक here

+2

"अगर यह अधिकतम मूल्य तक पहुंच जाता है तो बस एक जांच करें" - और आप इसकी कल्पना कैसे करते हैं? मैं खुद को अपवाद फेंकना नहीं चाहता, मुझे सटीक होना नहीं चाहिए। – jurchiks

+0

आप यह भी आजमा सकते हैं: लंबा सी = LongMath.checked जोड़ें (ए, बी); 2 लम्बे –

+1

@DanielA को संक्षेप में ओवरफ्लो होने पर यह अपवाद फेंकता है। शायद आपको जोड़ना चाहिए, इसके लिए आपको [गुवा पुस्तकालय] (http://code.google.com/p/guava-libraries/) की आवश्यकता है। – Baz

-1

LongMAX_VALUE से अधिक किसी भी अपवाद फेंक नहीं है मान पा सकते हैं। आपको मैन्युअल रूप से ऐसी स्थितियों की जांच और संभाल करने की आवश्यकता है।

जैसा कि @ पीटर लेवर ने सुझाव दिया है कि आपको double और BigInteger का उपयोग करने पर विचार करना चाहिए।

+0

आप इसे डबल के साथ कैसे करते हैं? एक BigInteger उदाहरण पोस्ट किया गया है, लेकिन डबल ... Long.MAX_VALUE के मूल्य को दोगुना करना और इसे प्रिंट करना मुझे 9.223372036854776E18' देता है। – jurchiks