यूंट बनाम इंट [बंद] का उपयोग करना


83

मैंने कुछ समय के लिए देखा है कि C # प्रोग्रामर हर जगह int का उपयोग करते हैं, और शायद ही कभी uint का सहारा लेते हैं। लेकिन मैंने कभी इसका संतोषजनक उत्तर नहीं खोजा कि क्यों।

यदि इंटरऑपरेबिलिटी आपका लक्ष्य है, तो uint को सार्वजनिक API में नहीं दिखना चाहिए क्योंकि सभी CLI भाषाएँ अहस्ताक्षरित पूर्णांक का समर्थन नहीं करती हैं। लेकिन यह स्पष्ट नहीं करता है कि आंतरिक कक्षाओं में भी इंट इतना प्रचलित क्यों है। मुझे संदेह है कि यही कारण है कि यूसीएल का उपयोग बीसीएल में संयम से किया जाता है।

C ++ में, यदि आपके पास एक पूर्णांक है जिसके लिए नकारात्मक मानों का कोई मतलब नहीं है, तो आप एक अहस्ताक्षरित पूर्णांक चुनते हैं।

यह स्पष्ट रूप से दर्शाता है कि नकारात्मक संख्याओं की अनुमति या अपेक्षा नहीं है, और संकलक आपके लिए कुछ जाँच करेगा। मुझे सरणी सूचकांकों के मामले में भी संदेह है, कि जेआईटी आसानी से निचले सीमा की जांच छोड़ सकती है।

हालांकि, इंट और यूनिट प्रकार को मिलाते समय, अतिरिक्त देखभाल और कलाकारों की आवश्यकता होगी।

क्या यूंट का अधिक उपयोग किया जाना चाहिए? क्यों?



बस थाउथ I एक देजा वु: डी, ​​लगभग ठीक उसी सवाल को पूछा गया है जबकि कुछ समय पहले।
— क्रोक्स

कम सीमा जांच के लिए के रूप में आप की जगह ले सकता (मामले में आप अपने खुद के लिखने की ज़रूरत) if (i < 0 || i >= length)के साथ if (unchecked((uint)i) >= length)। परिणामी IL में कुल में एक (शाखा) निर्देश कम होगा और लगभग एक ही प्रदर्शन (तेजी से तेजी से) देगा। व्यक्तिगत रूप से मैं इसे सिर्फ इसलिए प्यार करता हूं क्योंकि यह निचली सीमा की जाँच के खिलाफ मेरी खुजली को मिटा देता है। अन्य लोग "अनियंत्रित" होने के कारण इसके खिलाफ बहस करने की संभावना रखते हैं, लेकिन मेरा तर्क है कि यह इसका अर्थ सीखने के लिए एक बहुत अच्छी लाइन है क्योंकि यह सरल और तुरंत संदर्भ से स्पष्ट है कि उद्देश्य क्या है = पाठक को सीखने में मदद करता है।
— अनारकेन

यह उल्लेख करना भूल गए कि उपरोक्त 64 बिट्स पर इष्टतम है क्योंकि यह 64 बिट्स के साथ तुलना करेगा। 32 बिट के लिए बिल्ड if (unchecked((uint)i) >= unchecked((uint)length))बेहतर प्रदर्शन देता है। हालांकि यह बहुत जटिल दिखता है , और 64 बिट की तुलना अभी भी 32 डबल बिल्ड पर मानक डबल-ब्रांचिंग सीमा-जांच की तुलना में अधिक उत्कृष्ट है, इसलिए मैं वास्तव में किसी भी उचित स्थिति में इसकी सिफारिश नहीं कर सकता। (मैं ज्यादातर इसे इंगित करने के लिए उल्लेख कर रहा हूं कि 64-बिट की तुलना अन्यथा उपयोग की जाती है - जो कुछ के लिए उपयोगी जानकारी हो सकती है।)
— AnorZaken

सज्जनों, मेरा मानना ​​है कि आपका प्राथमिक मत आधार अच्छा नहीं है। यदि कोई उद्देश्य उत्तर संभव है, तो मैं एक के लिए, इसे सुनना चाहूंगा। मैं लाभ के लिए अपनी प्रथाओं को बदलने के लिए सभी हूँ।
— जोशुआ

जवाबों:


50

आपका uintBCL में उपयोग क्यों नहीं किया गया है इसका मुख्य कारण मुख्य कारण है, मुझे संदेह है।

UInt32 सीएलएस अनुरूप नहीं है, जिसका अर्थ है कि यह सार्वजनिक एपीआई में उपयोग के लिए पूरी तरह से अनुपयुक्त है। यदि आप अपने निजी API में uint का उपयोग करने जा रहे हैं, तो इसका अर्थ अन्य प्रकार के रूपांतरण करना होगा - और यह आमतौर पर आसान और सुरक्षित होता है ताकि प्रकार को समान रखा जा सके।

मुझे यह भी संदेह है कि यह C # विकास में सामान्य नहीं है, यहां तक ​​कि जब C # एकमात्र भाषा का उपयोग किया जा रहा है, मुख्यतः क्योंकि यह BCL में सामान्य नहीं है। डेवलपर्स, सामान्य रूप से, (धन्यवाद) फ्रेमवर्क की शैली की नकल करते हैं, जिस पर वे निर्माण कर रहे हैं - सी # के मामले में, इसका मतलब है कि आपके एपीआई, सार्वजनिक और आंतरिक बनाने की कोशिश करना, जितना संभव हो उतना .NET फ्रेमवर्क बीसीएल देखें। इसका मतलब यह होगा कि यूंट स्पैरेंट का उपयोग करना।


1
stackoverflow.com/questions/2013116/… एक ऐसा प्रश्न है जो एक समान विषय से संबंधित है
— Stephan

77

intसे टाइप करने के लिए कम है uint।


2
मुझे संदेह है कि यह सच्चाई के बहुत करीब है। uint99% समय का उपयोग क्यों करें (मेरे अनुभव में) intपर्याप्त होगा?
— मैथ्यू जोन्स

12
@ जस्टिन: "मैजिक नंबर" जैसे -1 सामान्य रूप से एक अच्छा विचार नहीं है। बिना किसी कारण के 2x मेमोरी का उपयोग करने के लिए लंबे समय तक स्विच करने का अर्थ है ... "यूनिट" निश्चित रूप से मूल्यवान है, बशर्ते आपको अन्य एपीआई के साथ बातचीत करने की आवश्यकता नहीं है।
— रीड कोपसे

28
मैं intकिसी एरे इंडेक्स का उपयोग करके कभी भी सहज महसूस नहीं करता , क्योंकि मैं कभी भी एक नकारात्मक इंडेक्स नहीं रखता। आँख बंद करके स्पष्ट लगता है कि uintइस मामले में इस्तेमाल किया जाना चाहिए।
— मार्क एच।

2
उल्लेख नहीं, अधिक पठनीय। यदि आप कभी भी किसी और को पढ़ने के लिए अपना कोड / एल्गोरिदम पास करते हैं जो आपसे कम अनुभवी हो सकता है, तो बहुत सारे का उपयोग करके uintउन्हें थोड़ा सा लटका दिया जा सकता है। intसभी परिस्थितियों में उपयोग करने के लिए पूरी तरह से स्वीकार्य है जहां आप उस सीमा को नियंत्रित करते हैं जो इसे ले जाएगी।
— drharris

3
@ मार्ख पूरी तरह से सहमत हैं, लेकिन रिवर्स पुनरावृत्ति करते समय यह के रूप में उपयोगी हो सकता है for (int i = arr.Length - 1; i >= 0; i--) { }:। एक उंट के साथ ऐसा करना एक अतिप्रवाह अपवाद या बदतर, एक अनंत लूप का परिणाम होगा।
— ऐदीकापी

19

सामान्य रूप intसे पर्याप्त होगा। यदि आप निम्नलिखित सभी शर्तों को पूरा कर सकते हैं, तो आप इसका उपयोग कर सकते हैं uint:

  • यह एक सार्वजनिक एपीआई के लिए नहीं है (चूंकि uintसीएलएस अनुपालन नहीं है)।
  • आपको नकारात्मक संख्याओं की आवश्यकता नहीं है।
  • आपको (अतिरिक्त) अतिरिक्त रेंज की आवश्यकता हो सकती है।
  • आप के साथ तुलना में इसका उपयोग नहीं कर रहे हैं < 0, जैसा कि कभी नहीं है true।
  • आप के साथ तुलना में इसका उपयोग नहीं कर रहे हैं >= 0, जैसा कि कभी नहीं है false।

अंतिम आवश्यकता अक्सर भूल जाती है और बग का परिचय देगी:

static void Main(string[] args)
{
    if (args.Length == 0) return;
    uint last = (uint)(args.Length - 1);

    // This will eventually throw an IndexOutOfRangeException:
    for (uint i = last; i >= 0; i--)
    {
        Console.WriteLine(args[i]);
    }
}

13

1) बुरी आदत। गंभीरता से। C / C ++ में भी।

सामान्य forपैटर्न के बारे में सोचो :

for( int i=0; i<3; i++ )
    foo(i);

पूर्णांक का उपयोग करने का कोई कारण नहीं है। आपके पास कभी भी नकारात्मक मूल्य नहीं होंगे। लेकिन लगभग हर कोई इस तरह से एक साधारण लूप करेगा, भले ही इसमें (कम से कम) दो अन्य "शैली" त्रुटियां हों।

2) intमशीन के मूल प्रकार के रूप में माना जाता है।


4

मैं पसंद uintकरता हूं intजब तक कि कोई नकारात्मक संख्या वास्तव में स्वीकार्य मूल्यों की सीमा में न हो। विशेष रूप से, एक intपरम को स्वीकार करना लेकिन ArgumentExceptionअगर संख्या शून्य से कम है तो फेंकना मूर्खतापूर्ण है - एक का उपयोग करें uint!

मैं सहमत हूं कि uintइसका उपयोग किया जा रहा है, और मैं सभी को इसे और अधिक उपयोग करने के लिए प्रोत्साहित करता हूं।


7
केवल संकेतों को स्वीकार करना और सीमाओं की जांच नहीं करना बहुत खतरनाक है। यदि कोई नकारात्मक मान से गुजरता है, तो CLR इसे एक बड़े इंट के रूप में व्याख्या करेगा, जिसका अर्थ है -1 के लिए आपको uint.maxvalue मिलता है। यह वांछित व्यवहार नहीं है।
— हेनरी

19
@ हेनरी: C # में इंट से uint तक कोई अंतर्निहित रूपांतरण नहीं है, इसलिए कोई "यदि कोई नकारात्मक मान पास करता है" नहीं है। बेशक ऊपरी सीमा पर एक सीमा की जांच अभी भी उपयुक्त है (लेकिन अब आपको दो के बजाय केवल एक चेक की आवश्यकता है)।
— बेन वोइगट

1

मैं निचले स्तर की एप्लिकेशन लेयर पर प्रोग्राम करता हूं, जहां ints शायद ही कभी 100 से ऊपर मिलता है, इसलिए नकारात्मक मान कोई समस्या नहीं है (उदाहरण के लिए i <myname.length () टाइप सामान) यह सिर्फ एक पुरानी सी आदत है - और जैसा कि ऊपर उल्लेख किया गया है। हालांकि, कुछ मामलों में, जब हार्डवेयर से इंटरफेस होता है, जहां मैं उपकरणों से घटना के झंडे के साथ काम कर रहा हूं, तो उन मामलों में uint महत्वपूर्ण है जहां एक झंडा बाईं ओर (सबसे अधिक) सबसे अधिक उपयोग कर सकता है।

ईमानदारी से, मेरे काम के 99.9% के लिए मैं आसानी से ushort का उपयोग कर सकता था, लेकिन int, आप जानते हैं, लगता है ushort से बहुत बेहतर है।


1

मैंने C # में एक Direct3D 10 रैपर बनाया है और अगर मुझे बहुत बड़े वर्टेक्स बफ़र बनाने हैं तो यूइंट का उपयोग करने की आवश्यकता है। वीडियो कार्ड में बड़े बफ़र्स को एक हस्ताक्षरित इंट के साथ प्रतिनिधित्व नहीं किया जा सकता है।

UINT बहुत उपयोगी है और अन्यथा कहने के लिए मूर्खतापूर्ण है। अगर किसी को लगता है कि सिर्फ इसलिए कि उन्हें कभी भी किसी और की इच्छा का उपयोग करने की आवश्यकता नहीं है, आप गलत हैं।


यह एक अच्छा मामला है जहां आप व्यापक रेंज का लाभ उठा सकते हैं।
— लियो गुरदियन

0

मुझे लगता है कि यह सिर्फ आलस्य है। सी # स्वाभाविक रूप से डेस्कटॉप और अन्य मशीनों पर अपेक्षाकृत अधिक संसाधनों के साथ विकास के लिए एक विकल्प है।

C, और C ++, हालांकि, पुराने सिस्टम और एम्बेडेड सिस्टम में गहरी जड़ें हैं जहां मेमोरी विरल है, इसलिए प्रोग्रामर का उपयोग सावधानी से सोचने के लिए किया जाता है कि डेटाटाइप का उपयोग क्या है। सी # प्रोग्रामर आलसी हैं, और चूंकि सामान्य रूप से पर्याप्त संसाधन हैं, कोई भी वास्तव में मेमोरी उपयोग का अनुकूलन करता है (सामान्य तौर पर, हमेशा नहीं)। घटना अगर एक बाइट पर्याप्त होगी, मेरे सहित बहुत सी # प्रोग्रामर, बस सादगी के लिए int का उपयोग करते हैं। इसके अलावा, एपीआई के बहुत सारे कार्य ints को स्वीकार करते हैं, इसलिए यह कास्टिंग को रोकता है।

मैं मानता हूं कि सही डेटाटाइप का चयन करना अच्छा अभ्यास है, लेकिन मुझे लगता है कि मुख्य प्रेरणा आलस्य है।

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


मैं यह नहीं कहूंगा कि यह आलस्य है, हालांकि आलस्य की यह विशेषता है। यह अधिक है कि ज्यादातर समय, मैं सिर्फ int / uint चीज के बारे में पर्याप्त परवाह नहीं करता हूं, इस तरह के निर्णय पर अपने मस्तिष्क चक्रों को बर्बाद करने के लिए, और बस int के साथ जाना। हार्डवेयर चीप है, प्रोग्रामर महंगे हो सकते हैं।
— स्वेको

प्रोग्रामर आलसी होते हैं। यह एक बुरी बात है। रेमंड कहेंगे कि प्रोग्रामर को अपने करों का भुगतान करने से नफरत है!
— लर्नोवा

मैं पहली बार प्रशासन करूंगा कि हमें C # प्रोग्रामर आलसी लगे लेकिन यह जरूरी नहीं है कि बुरी बात हो।
— चाओसपांडियन

@ लॉरेंजो, मैंने विश्वविद्यालय में एक लेख लिखा था, जिसमें कहा गया था कि एक आलसी प्रोग्रामर एक अच्छा प्रोग्रामर है। अधिकतर यह मशीन के समय के बजाय प्रोग्रामर समय के लिए अनुकूलन के बारे में था।
— एलॉफ

1
हम्म, अधिकांश प्रोग्रामर-अभेद्य कीड़े मैंने कभी देखा है (या किया है) आलस्य के कारण होता है ...
— लोरनोवा

0

मुझे लगता है कि इस कारण का एक बड़ा हिस्सा यह है कि जब सी पहली बार intसंक्षिप्तता के लिए इस्तेमाल किए गए अधिकांश उदाहरण सामने आए । हमने integerऐसा लिखने में आनन्द नहीं लिया, जैसे हमने फोरट्रान और पास्कल के साथ किया था, और उन दिनों में हमने सरणी सूचकांकों और पाश काउंटर जैसे सांसारिक चीजों के लिए नियमित रूप से उनका उपयोग किया था। अनइंस्टॉल किए गए पूर्णांक बड़ी संख्या के लिए विशेष मामले थे जिनकी अंतिम अतिरिक्त बिट की आवश्यकता थी। मुझे लगता है कि यह एक स्वाभाविक प्रगति है कि C आदतों को C # और पायथन जैसी अन्य नई भाषाओं में जारी रखा गया।


0

कुछ भाषाएं (उदाहरण पास्कल के कई संस्करण) सांख्यिक मात्रा का प्रतिनिधित्व करने के रूप में अहस्ताक्षरित प्रकारों का संबंध रखती हैं; एक अहस्ताक्षरित प्रकार और उसी आकार के एक हस्ताक्षरित प्रकार के बीच एक ऑपरेशन आम तौर पर किया जाएगा जैसे कि ऑपरेंड को अगले बड़े प्रकार में पदोन्नत किया गया था (कुछ ऐसी भाषाओं में, सबसे बड़े प्रकार का कोई अहस्ताक्षरित समकक्ष नहीं है, इसलिए ऐसा प्रचार हमेशा संभव होगा )।

अन्य भाषाएँ (जैसे C) N-bit अहस्ताक्षरित प्रकारों को एक समूह के रूप में मानती हैं जो modulo 2 ^ N के चारों ओर घूमता है। ध्यान दें कि ऐसे समूह के सदस्य से एन को घटाकर संख्यात्मक घटाव का प्रतिनिधित्व नहीं करता है, बल्कि समूह के सदस्य को पैदावार देता है, जब एन को इसमें जोड़ा जाता है, तो मूल उपज होगी। यकीनन, हस्ताक्षरित और अहस्ताक्षरित मूल्यों के मिश्रणों से जुड़े कुछ ऑपरेशनों का वास्तव में कोई मतलब नहीं है और उन्हें शायद मना किया जाना चाहिए, लेकिन यहां तक ​​कि कोड जो कि संख्यात्मक शाब्दिक चीजों की अपनी विशिष्टताओं के साथ मैला है, आमतौर पर काम करेगा, और कोड लिखा गया है, जो मिश्रित हस्ताक्षर किए गए हैं और अहस्ताक्षरित प्रकार और, मैला होने के बावजूद, काम करता है, कि कल्पना जल्द ही किसी भी समय बदलने के लिए उपयुक्त नहीं है।

हस्ताक्षरित और अहस्ताक्षरित प्रकारों के बीच बातचीत की सभी जटिलताओं को पूरा करने की तुलना में हस्ताक्षरित प्रकारों के साथ विशेष रूप से काम करना बहुत आसान है। छोटे टुकड़ों में से बड़ी संख्या को हटाते समय (जैसे क्रमांकन के लिए) या ऐसी संख्याओं को पुनर्गठित करने के लिए अनसाइन किए गए प्रकार उपयोगी होते हैं, लेकिन सामान्य तौर पर उन चीजों के लिए केवल हस्ताक्षरित संख्याओं का उपयोग करना बेहतर होता है जो वास्तव में मात्राओं का प्रतिनिधित्व करते हैं।


0

मुझे पता है कि यह शायद एक पुराना धागा है लेकिन मैं कुछ स्पष्टीकरण देना चाहता था।

आओ हम एक int8 लेते हैं जो आप स्टोर कर सकते हैं -128 से 127 और यह 1 बाइट का उपयोग करता है जो कुल 127 पॉजिटिव नंबर है।
जब आप एक int8 का उपयोग करते हैं तो बिट्स का उपयोग नकारात्मक संख्या -128 के लिए किया जाता है।
जब आप Uint8 का उपयोग करते हैं तो आप ऋणात्मक संख्याओं को सकारात्मक रूप से देते हैं जिससे आप 255 सकारात्मक संख्याओं को समान 1 भण्डार के साथ उपयोग कर सकते हैं।
एकमात्र ड्रा बैक आप नकारात्मक मानों का उपयोग करने की क्षमता खो चुके हैं।
इसके साथ एक और समस्या यह है कि सभी प्रोग्रामिंग भाषाएं और डेटाबेस इसका समर्थन नहीं करते हैं।
मेरी राय में इसका उपयोग करने का एकमात्र कारण यह है कि आपको गेमिंग प्रोग्रामिंग की तरह कुशल होने की आवश्यकता है और आपको बड़े गैर नकारात्मक संख्याओं को संग्रहीत करना होगा। यही कारण है कि कई कार्यक्रम इसका उपयोग नहीं करते हैं।

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

मुझे उम्मीद है कि यह किसी की मदद करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.