दिलचस्प पोस्ट
पहले से ही इसका समर्थन करने वाले ब्राउज़रों से एचटीएमएलआई इनपुट टाइप डेडेट टाइम क्यों है? एंड्रॉइड: केंद्र बिन्दु पर बिटमैप कैसे घुमाएगा सूची ड्रॉपडाउन सूची में विशेषताएँ पोस्टबैक पर खो जाती हैं? ngRepeat गहरा संपत्ति द्वारा फ़िल्टर करें विंडोज में क्रोन जॉब सेट करने के लिए php का उपयोग करें अजगर प्रोग्राम निष्पादन योग्य बनाने के लिए मैं लिनक्स पर क्या उपयोग करूँ? क्या JSR-303 (बीन सत्यापन) का कार्यान्वयन उपलब्ध है? एंड्रॉइड में यूएसबी डिबगिंग कैसे सक्षम करें? एक प्रपत्र में दर्ज करने के लिए दाब करने के लिए डिफ़ॉल्ट कार्रवाई जावास्क्रिप्ट में समय के अंतर की जांच करें ब्राउज़र कैशे में संग्रहीत jqGrid डेटा? कैसे गिट मर्ज विवाद को हल करने के लिए? android.os.FileUriExposedException: फ़ाइल: ///storage/emulated/0/test.txt Intent.getData () के माध्यम से ऐप से परे खुलासा एनजी-बाइन-एचटीएमएल-असुरक्षित कोएगल 1.2+ में दोहराने के लिए आप $ sce.trustAsHtml (स्ट्रिंग) का उपयोग कैसे करते हैं कैनवास कॉंटटेक्स 2 डी ड्रॉइमेज () मुद्दा

मैं कैसे जांच सकता हूं कि जावा में दो नंबरों को गुणा करना ओवरफ़्लो का कारण होगा?

मैं विशेष मामले को संभालना चाहता हूं जहां दो नंबरों को गुणा करना एक अतिप्रवाह का कारण बनता है। कोड कुछ ऐसा दिखता है:

int a = 20; long b = 30; // if a or b are big enough, this result will silently overflow long c = a * b; 

यह एक सरल संस्करण है असली प्रोग्राम a और b में रनटाइम पर कहीं और उपलब्ध हैं। मैं क्या हासिल करना चाहता हूं, ऐसा कुछ है:

 long c; if (a * b will overflow) { c = Long.MAX_VALUE; } else { c = a * b; } 

आप यह कैसे सबसे अच्छा कोड सुझाव है?

अद्यतन: a और b मेरे परिदृश्य में हमेशा गैर-नकारात्मक होते हैं।

वेब के समाधान से एकत्रित समाधान "मैं कैसे जांच सकता हूं कि जावा में दो नंबरों को गुणा करना ओवरफ़्लो का कारण होगा?"

जावा 8 में Math.multiplyExactMath.addExact Math.multiplyExact , Math.addExactMath.addExact आदि। ये अतिप्रवाह पर एक अनियंत्रित ArithmeticException फेंक देते हैं।

यदि a और b दोनों सकारात्मक हैं तो आप इसका उपयोग कर सकते हैं:

 if (a != 0 && b > Long.MAX_VALUE / a) { // Overflow } 

यदि आपको दोनों सकारात्मक और नकारात्मक संख्याओं से निपटने की आवश्यकता है तो यह अधिक जटिल है:

 long maximum = Long.signum(a) == Long.signum(b) ? Long.MAX_VALUE : Long.MIN_VALUE; if (a != 0 && (b > 0 && b > maximum / a || b < 0 && b < maximum / a)) { // Overflow } 

यहाँ एक छोटी सी मेज है जो मुझे यह जांचने के लिए दबाया गया था, यह बताते हुए कि अति-प्रवाह 10 या 10 पर होता है:

 a = 5 b = 2 2 > 10 / 5 a = 2 b = 5 5 > 10 / 2 a = -5 b = 2 2 > -10 / -5 a = -2 b = 5 5 > -10 / -2 a = 5 b = -2 -2 < -10 / 5 a = 2 b = -5 -5 < -10 / 2 a = -5 b = -2 -2 < 10 / -5 a = -2 b = -5 -5 < 10 / -2 

जावा पुस्तकालय हैं जो सुरक्षित अंकगणितीय संचालन प्रदान करते हैं, जो लंबे समय से ओवरफ्लो / अंडरफ्लो की जांच करते हैं। उदाहरण के लिए, पेरू के लोंगमाथ। चेकेड मैल्टिप्ली (इंट ए, इंट बी) a और b के उत्पाद को वापस प्रदान करता है, बशर्ते वह अतिप्रवाह नहीं करता है, और एरिथमेटिक एक्सपैशन को फेंकता है यदि a * b long अंकगणित पर हस्ताक्षर किए गए a * b ओवरफ्लो।

आप इसके बजाय java.math.BigInteger का उपयोग कर सकते हैं और परिणाम के आकार की जांच कर सकते हैं (कोड का परीक्षण नहीं किया है):

 BigInteger bigC = BigInteger.valueOf(a) * multiply(BigInteger.valueOf(b)); if(bigC.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) { c = Long.MAX_VALUE; } else { c = bigC.longValue() } 

परिणाम के आकार की जांच के लिए लॉगरिदम का उपयोग करें।

क्या जावा में int.MaxValue की तरह कुछ है? यदि हां, तो कोशिश करें

 if (b != 0 && Math.abs(a) > Math.abs(Long.MAX_VALUE / b)) { // it will overflow } 

संपादित करें: प्रश्न में लांग.एमएक्स_एवीएल देखा

मुझे यकीन नहीं है कि कोई भी समाधान की तरह क्यों नहीं देख रहा है:

 if (Long.MAX_VALUE/a > b) { // overflows } 

दो नंबरों में से एक बड़ा होना चुनें।

Jruby से चोरी हो

  long result = a * b; if (a != 0 && result / a != b) { // overflow } 

अद्यतनः यह कोड छोटा है और अच्छी तरह से काम करता है; हालांकि, यह एक = -1, बी = लोंग। MIN_VALUE के लिए विफल रहता है।

एक संभावित वृद्धि:

 long result = a * b; if( (Math.signum(a) * Math.signum(b) != Math.signum(result)) || (a != 0L && result / a != b)) { // overflow } 

ध्यान दें कि यह किसी भी विभाजन के बिना कुछ अतिप्रवाह को पकड़ेगा।

मैं जॉन कुगेलमैन के उत्तर पर इसे सीधे संपादन के बजाय इसे बदलने के बिना बनाना चाहता हूं यह MIN_VALUE == -MAX_VALUE की सममितता के कारण अपने परीक्षण के मामले ( MIN_VALUE = -10 , MAX_VALUE = 10 ) के लिए काम करता है, जो दो पूरक पूरकताओं के मामले में नहीं है। वास्तविकता में, MIN_VALUE == -MAX_VALUE - 1

 scala> (java.lang.Integer.MIN_VALUE, java.lang.Integer.MAX_VALUE) res0: (Int, Int) = (-2147483648,2147483647) scala> (java.lang.Long.MIN_VALUE, java.lang.Long.MAX_VALUE) res1: (Long, Long) = (-9223372036854775808,9223372036854775807) 

जब सही MIN_VALUE और MAX_VALUE लागू होता है, तो जॉन कुगेलमैन के उत्तर में a == -1 और b == और कुछ भी होता है (पहले काइल द्वारा उठाया गया बिंदु) एक अतिप्रवाह केस उत्पन्न करता है। इसे ठीक करने का एक तरीका यहां है:

 long maximum = Long.signum(a) == Long.signum(b) ? Long.MAX_VALUE : Long.MIN_VALUE; if ((a == -1 && b == Long.MIN_VALUE) || (a != -1 && a != 0 && ((b > 0 && b > maximum / a) || (b < 0 && b < maximum / a)))) { // Overflow } 

यह किसी भी MIN_VALUE और MAX_VALUE लिए एक सामान्य समाधान नहीं है, लेकिन यह जावा के Long और Integer के लिए सामान्य a और b और b किसी भी मूल्य के लिए a

शायद:

 if(b!= 0 && a * b / b != a) //overflow 

इस "समाधान" के बारे में निश्चित नहीं है

संपादित करें: जोड़ा गया बी! = 0

इससे पहले कि आप डाउनवॉइट : ए * बी / बी अनुकूलित नहीं होंगे यह संकलक बग होगा मुझे अभी भी कोई ऐसा मामला दिखाई नहीं देता जहां अतिप्रवाह बग नकाबपोश किया जा सकता है।

शायद यह आपकी मदद करेगा:

 /** * @throws ArithmeticException on integer overflow */ static long multiply(long a, long b) { double c = (double) a * b; long d = a * b; if ((long) c != d) { throw new ArithmeticException("int overflow"); } else { return d; } } 

जैसा कि बताया गया है, जावा 8 में Math.xxxExact विधियां हैं जो अतिप्रवाह पर अपवाद फेंकती हैं।

यदि आप अपनी परियोजना के लिए जावा 8 का उपयोग नहीं कर रहे हैं, तो आप अभी भी उनके कार्यान्वयन "उधार ले सकते हैं" जो बहुत कॉम्पैक्ट हैं

यहां 3 पार्टी की वेबसाइट पर इन कार्यान्वयन के कुछ लिंक हैं, इसकी कोई गारंटी नहीं है कि ये मान्य रहेंगे लेकिन किसी भी मामले में आप जेडीके के स्रोत में जा सकते हैं और देखेंगे कि वे कैसे अपने जादू को java.lang.Math क्लास के अंदर करते java.lang.Math

Math.multiplyExact(long, long) http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/lang/Math.java?av=f#882

Math.addExact http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/lang/Math.java?av=f#805

आदि आदि।

यहां सबसे आसान तरीका है जो मैं सोच सकता हूं

 int a = 20; long b = 30; long c = a * b; if(c / b == a) { // Everything fine.....no overflow } else { // Overflow case, because in case of overflow "c/b" can't equal "a" } 

सी / सी ++ (लंबी * लंबी):

 const int64_ w = (int64_) a * (int64_) b; if ((long) (w >> sizeof(long) * 8) != (long) w >> (sizeof(long) * 8 - 1)) // overflow 

जावा (int * int, माफ़ करना मुझे जावा में int64 नहीं मिला):

 const long w = (long) a * (long) b; int bits = 32; // int is 32bits in java if ( (int) (w >> bits) != (int) (w >> (bits - 1))) { // overflow } 

1. बड़े प्रकार में परिणाम (int * int, लंबे, लंबे * int64 के लिए रखा लंबे समय तक परिणाम डाल)

2. सीएमएम परिणाम >> बिट और परिणाम >> (बिट्स – 1)