2015-11-04 9 views
8

कैसे हैं निम्नलिखित कोड व्यवहार, खासकर जब डबल काउंटर अपनी सीमा ((2-2^-52) · 2^1023) तक पहुँच जाता है?(जावा) पाश के लिए में Double.POSITIVE_INFINITY का उपयोग

for (double i = 0; i < Double.POSITIVE_INFINITY; i++){ 
    //do something 
} 

क्या यह कोड अपेक्षित (लूप हमेशा के लिए) व्यवहार करेगा या किसी बिंदु पर विफल होगा और क्यों?

धन्यवाद।

+0

मैं बहस चाहते हैं कोई गारंटी नहीं है कि यह यह है कि मूल्य के लिए बनाती हूँ यह है कि। कौन कहने वाला है कि डबल अंकगणितीय व्यवहार के तरीके के कारण उस मूल्य तक पहुंचने से पहले मैं नीचे नहीं आऊंगा? – Makoto

+0

क्यों न सिर्फ कोशिश करें? – Grodriguez

+0

@ मकोटो यह मूल रूप से मैं पूछ रहा हूं। यहां एकमात्र दिलचस्प मामला एज केस है। – Samir

उत्तर

5

इस कोड को लूप से बाहर निकलने कभी नहीं होगा।

इस का कारण यह है कि एक पर्याप्त रूप से बड़े double संख्या के लिए 1 जोड़ने अपने मूल्य परिवर्तन नहीं करता है: जब double का मूल्य पर्याप्त सकारात्मक अनंत के करीब हो जाता

double a = 1.7976931348623155E308; 
double old = a; 
a++; 
System.out.println(a);  // prints 1.7976931348623155E308 
System.out.println(old); // prints 1.7976931348623155E308 
System.out.println(a==old); // prints "true" 

Demo.

वास्तव में, , आप अच्छी तरह से 10 ऊपर एक नंबर जोड़ने के लिए अपने बड़े डबल परिवर्तन मूल्य बनाने के लिए और POSITIVE_INFINITY बनने के लिए की जरूरत है।

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

अपने double संख्या के माध्यम से संख्या परिवर्तन मूल्य जोड़ने के लिए, आपको उस संख्या को जोड़ना होगा जो कम से कम मंटिसा के महत्वपूर्ण रूप से महत्वपूर्ण हो। एक बार बाइनरी एक्सपोनेंट 48 से ऊपर हो जाने के बाद, परिणाम के लिए आपको सबसे छोटी संख्या को जोड़ने की आवश्यकता होती है, जिसका अर्थ है कि ++ अब मान को बदल नहीं पाएगा।

+0

क्या इसका पूरा 0 प्रभाव है? बिट्स या मेमोरी में कोई बदलाव नहीं है? या बड़ी संख्या में लोगों के प्रभाव का असर होगा? इसके अलावा "पर्याप्त रूप से बड़ा" वास्तव में क्या मतलब है? – Samir

+2

@ सैमिर एक बड़ी संख्या में जोड़ने से कोई प्रभाव नहीं पड़ता है। एक बार फ्लोटिंग पॉइंट यूनिट देखता है कि दो नंबरों के एक्सपोनेंट्स को उनके मंटिसास को गैर-अंतरंग श्रेणियों में डाल दिया जाता है, इकाई बंद हो जाती है, और बड़ी संख्या का मान देता है। – dasblinkenlight

6

कुछ बिंदु पर, i++ क्योंकि i के बहुत बड़े मूल्यों के लिए, किसी भी प्रभाव पड़ रहा बंद हो जाएगा, लगातार double मूल्यों में अंतराल है।

इसलिए यह अनंत लूप है।

जिसके लिए double मूल्यों देखते हैं साबित करने के लिए i == i + 1 इस प्रयास करें:

for (double i = 1;; i *= 2){ 
    if (i == i + 1) { 
     System.out.println(i); 
     break; 
    } 
} 

यह प्रिंट

9.007199254740992E15 
+0

यह दिलचस्प है, उसे नहीं पता था। क्या वृद्धि दर हमेशा के लिए प्रभावी हो रही है या बदलाव देखने के लिए वास्तव में काफी समय लगता है? इस लूप के साथ काउंटर कभी भी बह जाएगा? – Samir

+2

@ सैमिर इसका कोई प्रभाव नहीं पड़ता है। यह "गुप्त रूप से" कहीं वृद्धि को संरक्षित नहीं करता है; एक बार 'i' काफी बड़ा हो जाने पर कोई बदलाव नहीं होता है। एक बार 'i' उस मान पर पहुंच जाता है, तो यह पूरी तरह से बदल रहा है _। –

+0

@ सैमिर फ़्लोटिंग पॉइंट मानों में अनंत रिज़ॉल्यूशन नहीं है https://en.wikipedia.org/wiki/Unit_in_the_last_place वह न्यूनतम "चरण" है जिसे आपको जाना है। इस बिंदु पर 1 – zapl

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