2015-06-02 9 views
17
long m = 24 * 60 * 60 * 1000 * 1000; 

उपरोक्त कोड अतिप्रवाह बनाता है और सही परिणाम मुद्रित नहीं करता है।गुणा के साथ ओवरफ्लो होता है

long m2 = 24L * 60 * 60 * 1000 * 1000; 
long m3 = 24 * 60 * 60 * 1000 * 1000L; 

उपरोक्त 2 पंक्तियां सही परिणाम प्रिंट करती हैं।

मेरे सवालों का कर रहे हैं-

  1. यह संकलक जो मैं का उपयोग करें, m2 या m3 कोई फर्क पड़ता है?
  2. जावा गुणा कैसे शुरू करता है? बाएं से दाएं या दाएं से बाएं? क्या 24 * 60 पहले या 1000 * 1000 की गणना की जाती है?
+1

ओप्स- लंबा एम 2 = 24 एल * 60 * 60 * 1000 * 1000 * 1000 * 1000; लंबे एम 3 = 24 * 60 * 60 * 1000 * 1000 * 1000 * 1000 एल; एम 2 और एम 3 एक ही परिणाम नहीं देते हैं जब 1000 * 1000 के एक कारक द्वारा अधिक mutiplied कहते हैं। तो ऐसा लगता है गुणा से बाएं से दाएं होता है। – rents

+2

दाएं, 'm2' का उपयोग करें ताकि प्रत्येक मध्यवर्ती गुणा को 'लंबे' तक बढ़ावा दिया जा सके। गुणा बाएं-सहयोगी है, इसलिए यह बाएं से दाएं चला जाता है। – GriffeyDog

+0

गुणात्मक सहयोगी है, इसलिए आदेश कोई फर्क नहीं पड़ता। हालांकि यह मामलों में बाएं से दाएं गणना की जाती है, इससे कोई फर्क नहीं पड़ता कि कॉलिंग विधियां जो संख्या लौटाती हैं। –

उत्तर

16

मैं m3 लाइन के बजाय m2 लाइन का उपयोग करूंगा।

जावा गुणात्मक ऑपरेटर *left to right से मूल्यांकन करता है, इसलिए 24 * 60 का मूल्यांकन पहले किया जाता है।

यह सिर्फ इतना है कि 24 * 60 * 60 * 1000 (एक 1000), अतिप्रवाह नहीं करता है तो उस समय तक आप 1000L (दूसरा 1000) से गुणा, उत्पाद long करने के लिए प्रोत्साहित किया जाता है गुणा से पहले, ताकि अतिप्रवाह नहीं ले करता है जगह।

लेकिन जैसा कि आपने अपनी टिप्पणियों में उल्लेख किया है, पिछले long संख्या को गुणा करने से पहले int डेटा प्रकार में अधिक कारक ओवरफ्लो का कारण बन सकते हैं, गलत जवाब दे रहे हैं। शुरुआत से ओवरफ़्लो से बचने के लिए m2 में पहले (बाएं-सबसे) संख्या के लिए long शाब्दिक उपयोग करना बेहतर है। वैकल्पिक रूप से, आप पहले अक्षर को long के रूप में डाले जा सकते हैं, उदा। (long) 24 * 60 * ...

19

इस मामले में -

long m = 24 * 60 * 60 * 1000 * 1000; 

काम के अधिकार पहले मूल्यांकन किया जाता है। दाईं ओर कोई long प्रकार डेटा नहीं है। सभी int हैं। तो JVM परिणाम को int में फ़िट करने का प्रयास करें, तो अतिप्रवाह हुआ।

और दूसरे मामले में - गुणा के

long m2 = 24L * 60 * 60 * 1000 * 1000; 
long m3 = 24 * 60 * 60 * 1000 * 1000L; 

यहाँ एक संकार्य long है। तो अन्य को स्वचालित रूप से long पर संकेत दिया जाता है। परिणाम long पर फिट करने का प्रयास कर रहा है। अंत में असाइनमेंट m2 और m3 के साथ किया जाता है।

और हां गुणा से दाएं से दाएं की साझेदारी - मतलब बाएं ऑपरेंड पहले लिया जाता है। और मैं इस परिदृश्य में लगता है कि इस तथ्य के आधार पर हम का उपयोग करना चाहिए -

long m2 = 24L * 60 * 60 * 1000 * 1000; 

इस बयान, इस बयान long लिया स्थानों के लिए पदोन्नति पहले जो अतिप्रवाह के खतरे को कम से कम के बाद से।

+0

"असाइनमेंट का बायां पहले मूल्यांकन किया जाता है।" ... क्या आपका मतलब सही था? – Mints97

+0

अभी भी दूसरी वाक्य में एक टाइपो है :) – Ruslan

+0

@Ruslan, मुझे लगता है कि मुझे बाएं-दाएं समस्या है :(धन्यवाद – Razib

6

बाएं से दाएं कामों को गुणा करना, और int * intint उत्पन्न करता है।तो

24 * 60 * 60 * 1000 * 1000 

रूप

(((24 * 60)* 60) * 1000) * 1000 

जो हमें

(((1440)* 60) * 1000) * 1000 
(( 86400 ) * 1000) * 1000 
( 86400000  ) * 1000 

और अंत में पूर्णांक अतिप्रवाह की वजह से (के बाद से 86400000000 पूर्णांक लिए बहुत बड़ी है जो अधिकतम मूल्य 2147483647 है) परिणाम होगा देता है एक ही है

500654080 

आप तर्कों में से एक के रूप में long का उपयोग करके पूर्णांक ओवरफ़्लो को समाप्त कर सकते हैं (int * long और long * intlong उत्पन्न करता है)।

इस मामले आप शुरू में यह कर सकते हैं जैसे आप m2 के मामले में किया था में: 24L * 60 जो long1440L जो फिर पूर्णांक 60 से गुणा किया जाएगा नया long उत्पादन का उत्पादन करेगा, और इतने पर, केवल long मूल्यों का निर्माण किया।

m3 मामले यहाँ काम करता है क्योंकि आप 864000001000L से जिसका अर्थ है कि आप पूर्णांक अतिप्रवाह से परहेज कर रहे हैं के बाद से परिणाम long हो जाएगा गुणा कर रहे हैं।

9

Since expressions are evaluated from left to right, मैं आपका पहला समाधान (m2 = ...) पसंद करूंगा।

तर्क: चलिए थोड़ा अलग उदाहरण देखें।

long l = Integer.MAX_VALUE * 2 * 2L; 

यह अभिव्यक्ति (क्योंकि दोनों ऑपरेंड int हैं जो समय में इस बिंदु पर -2 है,) के बाद से ही पिछले गुणा long करने के लिए पहली अभिव्यक्ति डाले -4 करने का मूल्यांकन करेंगे। आप

long l = Integer.MAX_VALUE * 2L * 2; 

बजाय लिखते हैं, l8589934588 की उम्मीद मूल्य का आयोजन करेगा के बाद से पहली गुणा प्रकार long का एक परिणाम अर्जित करता है।

4

के अधिक संख्याओं को गुणा करते हैं, इस लाइन अतिप्रवाह होगा भी नहीं है एक 1000L:

long m3 = 24 * 60 * 60 * 1000 * 1000 * 1000 * 1000L; 

यह सही परिणाम दे देंगे जबकि:

long m3 = 24L * 60 * 60 * 1000 * 1000 * 1000 * 1000; 

तो हम यह सुनिश्चित करें कि जावा बाएं से गुणा शुरू कर रहे हैं सही करने के लिए और हमें ओवरफ्लो को रोकने के लिए बाईं ओर से Long से शुरू करना होगा।

2

ऐसा इसलिए है क्योंकि जब हम एक ऑपरेंड के रूप में लंबे समय तक उपयोग करते हैं तो अन्य सभी int प्रकार ऑपरेंड long पर संकेत मिलता है।

जावा में अभिव्यक्ति बाएं से दाएं से मूल्यांकन की गई।

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