2013-04-17 8 views
19

जावा स्ट्रिंग source code में क्या मतलब है, वहाँ कुछ स्थानों रहे हैं निम्नलिखित टिप्पणी के साथ कहा:"ऑफसेट या गिनती -1 >>> 1 के करीब हो सकती है।" यह

// Note: offset or count might be near -1>>>1. 

निम्न उदाहरण पर विचार करें:

public String(char value[], int offset, int count) { 
    if (offset < 0) { 
     throw new StringIndexOutOfBoundsException(offset); 
    } 
    if (count < 0) { 
     throw new StringIndexOutOfBoundsException(count); 
    } 
    // Note: offset or count might be near -1>>>1. 
    if (offset > value.length - count) { 
     throw new StringIndexOutOfBoundsException(offset + count); 
    } 
    this.offset = 0; 
    this.count = count; 
    this.value = Arrays.copyOfRange(value, offset, offset+count); 
} 

हम देख सकते हैं, offset, value.length और count सभी int हैं, इस प्रकार मान -1, 0, 1, या किसी अन्य पूर्णांक हो सकता है। टिप्पणी में "नज़दीक" और ">>>" का अर्थ क्या है, क्या मुझे यहां कुछ याद आ रही है?

+6

'-1 >>> 1' 'Integer.MAX_VALUE' – soulcheck

उत्तर

20

मूल्य -1>>>1 == 2147483647 अधिकतम int मान है जो आपके पास जावा में हो सकता है।

दूसरे शब्दों में, -1>>>1 == Integer.MAX_VALUE। जब आप ऐसी सीमाओं के करीब मूल्यों के साथ गणित करते हैं, तो आप अप्रत्याशित परिणाम प्राप्त करने की संभावनाओं को बढ़ाते हैं। उदाहरण के लिए, int a = (-1>>>1); System.out.println(a < a + 1); एक पूर्णांक अतिप्रवाह की वजह से प्रिंट false, एक है कि कोड हमेशा की तरह, true के बाद से मुद्रित करने के लिए शुद्ध गणित में, किसी भी पूर्णांक n के लिए यह सच है कि n < n + 1 उम्मीद कर सकता है, भले ही।

कोड के उस टुकड़े के लेखक सिर्फ उसके (बुद्धिमान)

if (offset > value.length - count) 
समान दिखने वाले बल्कि नहीं के बराबर

if (offset + count > value.length) 

इस के बजाय

लिखने के निर्णय समझा रहा है अंतिम संस्करण एक पूर्णांक ओवरफ़्लो का कारण बन सकता है, जो निम्नानुसार कोड के लिए एक बड़ी समस्या हो सकती है। वह इस तथ्य को सतर्क कर रहे हैं कि संभावना है कि कम से कम offset या countInteger.MAX_VALUE के करीब एक मूल्य हो सकता है, जो ओवरफ़्लो की संभावना को बढ़ाता है।

पहले संस्करण (स्ट्रिंग तुम उल्लेख के लिए स्रोत कोड में प्रयोग किया जाता है), वहाँ एक अतिप्रवाह कभी नहीं हो सकता है: आप सुनिश्चित करें कि दोनों offset और count सकारात्मक या क्योंकि पिछले चेकों के 0 कर रहे हैं के लिए जानते हैं, और value.length है सकारात्मक या 0 क्योंकि जावा में एक सरणी की लंबाई हमेशा सकारात्मक या 0 होती है, इसलिए कोई अतिप्रवाह समस्या नहीं हो सकती है!

पसंद को दस्तावेज करने के अलावा, लेखक अन्य डेवलपर्स (अपने भविष्य के स्वयं सहित) को चेतावनी देता है कि उस लाइन को जिस तरह से लिखा जा सकता है, उससे बचने के लिए एक बहुत ही विशिष्ट कारण है, जो इसे बदलने के लिए लुभाने वाले किसी भी व्यक्ति से बचने के लिए है (संभवतः अधिक प्राकृतिक लग रहा है) दूसरा, गलत संस्करण एक बग शुरू करने से।

+0

में छोड़ा है जो उस कोड को लिखने वाले लेखक से अच्छी तरह से सोचा जाता है। – zynick

+0

सिर्फ उत्सुक है, लेखक ने "ऑफसेट या गिनती" Integer.MAX_VALUE "के बजाय क्यों नहीं लिखा है? हालांकि Integer.MAX_VALUE अस्पष्ट है, कम से कम यह समझना आसान होगा। आखिरकार, टिप्पणी का बिंदु कोड बदलने पर संभावित इंटीजर ओवरफ्लो के भविष्य के डेवलपर्स को चेतावनी देना है। – zynick

+0

@ ज़िनिक: "समझने में आसान" रिश्तेदार है, आप कहां से आते हैं, आपके अनुभवों के आधार पर। और ध्यान रखें: यह सार्वजनिक दस्तावेज नहीं है जो ऑप्टिमाइज़ करने के लिए एक प्रलेखन टीम के माध्यम से चला गया। यह केवल एक नोट है कि एक जेडीके डेवलपर ने भविष्य के सभी डेवलपर्स के लिए लिखा है जो उस कोड को छूते हैं। यह अनौपचारिक है और इसे रखने के लिए सबसे अच्छा संभव तरीका नहीं है। –

5

आप >>> ऑपरेटर के बारे में विवरण के लिए Bitwise and Bit Shift Operators को देखने के लिए चाहते हो सकता है:

अहस्ताक्षरित सही पारी ऑपरेटर ">>>" वाम-पंथी स्थिति

आप कहो में एक शून्य बदलाव है:

int a = -1; 
a = a >>> 1; 
System.out.println(a); 

फिर a 2147483647 (जो होगा Integer.MAX_VALUE)

क्यों?

चूंकि >>> ऑपरेटर ज़ीरो भरता है और केवल शून्य सकारात्मक और नकारात्मक संख्या से कोई फर्क नहीं पड़ता। तो, उदाहरण के लिए, यदि आपके पास:

12 >>> 2

(00000000 00000000 00000000 000011 00 >>> 2) तो परिणाम 3.

है (जो 00000000 00000000 00000000 00,000,011 है)।

इसलिए, यदि आप यह करेंगे:

System.out.println(Integer.toBinaryString(-1>>>1)); 

यह प्रिंट होगा:

1111111111111111111111111111111 

और निश्चित रूप से, यह दशमलव में परिवर्तित करने, इस 2147483647

के रूप में @ है BrunoReis (+1) ने अपने जवाब में समझाया, ऐसा करने का कारण संभावित पूर्णांक अतिप्रवाह समस्याओं को रोकने के लिए है।

+0

कहने का एक अप्रिय तरीका है बेहतर समझने के लिए आपको समझाया जाना चाहिए कि दो के पूरक संख्या का प्रतिनिधित्व क्या है। अभी यह स्पष्ट नहीं है कि क्यों 1111111111111111111111111111111 -1 और 0111111111111111111111111111111 अधिकतम मान है। – Mikhail

+2

बिट को पूर्णांक में कैसे काम करता है, यह समझाने के लिए धन्यवाद, मैंने गलती से मेरे कॉलेज – zynick

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