ऐसे कौन से मामले हैं जब 'यूंट' और 'शॉर्ट' डेटाटाइप मानक इंट (32) की तुलना में बेहतर हैं?


24

मैं क्षमता और मूल्यों के अंतर को समझता हूं जो वे प्रतिनिधित्व कर सकते हैं लेकिन ऐसा लगता है जैसे लोग हमेशा इसका उपयोग करते Int32हैं चाहे वह उचित हो। कोई भी कभी भी अहस्ताक्षरित संस्करण ( uint) का उपयोग नहीं करता है, भले ही यह बहुत समय से बेहतर हो, क्योंकि यह एक ऐसे मूल्य का वर्णन करता है जो नकारात्मक नहीं हो सकता है (शायद एक डेटाबेस रिकॉर्ड की आईडी का प्रतिनिधित्व करने के लिए)। इसके अलावा, कोई भी कभी भी short/Int16मूल्य की आवश्यक क्षमता की परवाह किए बिना उपयोग नहीं करता है ।

वस्तुतः, क्या ऐसे मामले हैं जहां इसका उपयोग करना बेहतर है uintया short/Int16यदि ऐसा है, तो वे कौन से हैं?


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


1
संक्षिप्त उत्तर, मुझे लगता है कि प्रोग्रामर ने हस्ताक्षर किए हुए शब्दार्थों का उपयोग किया है और उन लोगों को मानने के लिए इच्छुक हैं, भले ही अहस्ताक्षरित प्रकारों (और इस प्रकार अहस्ताक्षरित शब्द) से निपट रहे हों। अधिकांश लोग यह मान लेते हैं कि यह प्रोग्रामर के आलसी या अशिक्षित होने की बात है, लेकिन विचाराधीन प्रोग्रामर वास्तव में बहुत शिक्षित और बहुत सावधान हो सकता है और सूक्ष्म नुकसान से बचना चाहता है। अगर आपको पसंद है, तो ध्वनिरहित .ac.uk / c - pitfall- unsigned और anteru.net/2010/05/17/736 पर एक नज़र डालें
थियोडोरोस चट्जीगनिनाकिस

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

1
मेरे अनुभव में बहुत से प्रोग्रामर, जिन्होंने कभी सी भाषा में प्रोग्राम किया है, बाइट्स की परवाह करते हैं, इन दिनों में, जीबी की मेमोरी और स्टोरेज स्पेस की भी।
user1451111

जवाबों:


25

मुझे संदेह है कि आप अपने स्वयं के अनुभवों द्वारा रंगीन परिप्रेक्ष्य का उल्लेख कर रहे हैं जहां आपने उन लोगों के आसपास काम नहीं किया है जो अभिन्न प्रकार का उपयोग करते हैं। यह अच्छी तरह से एक सामान्य घटना हो सकती है, लेकिन यह मेरा अनुभव है कि लोग आमतौर पर उनका सही इस्तेमाल करते हैं।

लाभ मेमोरी स्पेस और सीपीयू समय है, संभवतः IO स्पेस के साथ-साथ यह भी निर्भर करता है कि क्या प्रकार कभी तार पर या किसी डिस्क पर भेजे जाते हैं। अहस्ताक्षरित प्रकार आपको यह सुनिश्चित करने के लिए संकलक चेक प्रदान करते हैं कि आप कुछ ऐसे संचालन नहीं करेंगे जो असंभव हैं, साथ ही बढ़े हुए प्रदर्शन के लिए छोटे आकार को बनाए रखते हुए उपलब्ध रेंज का विस्तार करना जहां यह आवश्यक हो सकता है।

सही उपयोग के रूप में आप उम्मीद करेंगे है - कभी भी आप जानते हैं कि कुछ के लिए आप उन्हें इस्तेमाल कर सकते हैं स्थायी रूप से (निश्चितता के बिना विवश नहीं कर सकते हैं या आप होगा यह बाद में पछताना)।

  • यदि आप किसी ऐसी चीज़ का प्रतिनिधित्व करने की कोशिश कर रहे हैं जो कभी भी नकारात्मक नहीं हो सकती ( public uint NumberOfPeople) एक अहस्ताक्षरित प्रकार का उपयोग करें।
  • यदि आप किसी ऐसी चीज़ का प्रतिनिधित्व करने की कोशिश कर रहे हैं जो कभी भी 255 से अधिक नहीं हो सकती है ( public byte DamagedToothCount), एक बाइट का उपयोग करें।
  • यदि आप किसी ऐसी चीज़ का प्रतिनिधित्व करने की कोशिश कर रहे हैं जो कि 255 से अधिक हो सकती है, लेकिन कभी भी हजारों की संख्या में नहीं , तो एक छोटी ( public short JimmyHoffasBankBalance) का उपयोग करें ।
  • यदि आप किसी ऐसी चीज़ का प्रतिनिधित्व करने की कोशिश कर रहे हैं जो कई सैकड़ों हजारों, लाखों भी हो सकती है, लेकिन कई अरबों तक पहुंचने की संभावना नहीं है, तो एक इंट ( public int HoursSinceUnixEpoch) का उपयोग करें ।
  • यदि आप कुछ के लिए जानते हैं तो इस संख्या का एक बड़ा मूल्य हो सकता है या आपको लगता है कि इसमें कई बिल हो सकते हैं, लेकिन आप निश्चित नहीं हैं कि कितने बिलियन हैं, लंबे समय तक आपका सबसे अच्छा दांव है। यदि लंबे समय तक पर्याप्त बड़ा नहीं है, तो आपके पास एक दिलचस्प समस्या है और मनमाने ढंग से सटीक संख्या विज्ञान ( public long MyReallyGreatAppsUserCountThisIsNotWishfulThinkingAtAll) को देखना शुरू करना होगा ।

इस तर्क का उपयोग हस्ताक्षरित, अहस्ताक्षरित और विभिन्न प्रकार के एट अल के बीच चयन करने में किया जा सकता है, बस उस डेटा की तार्किक सत्यता के बारे में सोचें जिसका आप वास्तविकता में प्रतिनिधित्व कर रहे हैं।


11
+1, हालाँकि मुझे यह स्पष्ट करना होगा कि फ़ोन "संख्या" संख्या नहीं है, लेकिन अंकों के तार और वैकल्पिक रूप से स्वरूपण हैं। आप इसके बारे में जानते हैं, लेकिन हम एक बुरा उदाहरण स्थापित नहीं करना चाहते हैं, अब हम करते हैं? इसके अलावा, कुछ मूल्य की सीमा को मनमाने ढंग से प्रतिबंधित करना एक अदूरदर्शी एंटीपैटर्न है - intहर जगह जब तक आप इस तथ्य के लिए नहीं जानते कि समस्या डोमेन वास्तव में मूल्य को प्रतिबंधित करता है - कोई भी बैंक हार्ड-लिमिट खातों को 33K क्विड (और मज़े के बारे में सोचना) नहीं चाहेगा। जब वह ओवरफ्लो होता है ...!)।
आमोन

3
नया जीवन लक्ष्य: बड़े आकार का ओवर ड्राफ्ट जो मेरे बैंक खाते के अभिन्न प्रकार को कम करता है।
recursion.ninja

11
कुछ स्थानों पर अहस्ताक्षरित प्रकारों का उपयोग न करने के अच्छे कारण हैं, उदाहरण के लिए, जब अंकगणित को हस्ताक्षरित और अहस्ताक्षरित के बीच मिलाया जाता है। देखें कि अहस्ताक्षरित चींटियों के बारे में सबसे अच्छा अभ्यास क्या हैं?

19
मैं यहां तर्क से असहमत हूं। यदि टाइप्स में उपयोग किया जाता है (तो वे सुसंगत तरीके से काम करते हैं लेकिन यह हमेशा "सकारात्मक" नहीं होता है) क्योंकि घटाव और तुलना अप्रत्याशित होने के कारण अनसाइन किए गए प्रकार अक्सर एक गलती होते हैं। जब तक आपके पास उनका उपयोग करने के लिए कोई विशेष कारण न हो, मैं उनसे बचूंगा। इसके अलावा, बाइट बनाम शॉर्ट बनाम इंट के लिए आकार क्यों मायने रखता है? आप अक्सर स्थान भी नहीं बचाते हैं, क्योंकि संरचना उन सदस्यों या सरणियों को एक निश्चित संरेखण में पैड कर देगी। मैं केवल एक बाइट का उपयोग करता हूं यदि आकार वास्तव में महत्वपूर्ण है (विशेष रूप से सी # कोड की संभावना नहीं है) या यदि आप विशेष रूप से किसी चीज़ के लिए 255 पर रैपराउंड चाहते हैं।
एडम डी। रूपे

4
"लाभ मेमोरी स्पेस और सीपीयू समय है" ... मुझे कोई भी मामला नहीं दिखता है जहां छोटे-प्रकार वास्तव में सीपीयू समय बचा सकते हैं। मशीन के आकार के प्रकारों पर इंटीजर ऑपरेशन कभी तेज नहीं होते हैं , यानी जहां तक ​​सीपीयू की बात है तो आप भी इसका इस्तेमाल कर सकते हैं long। मेमोरी सेविंग बेशक कैश-लाइन दक्षता और इतने पर सुधार करके अप्रत्यक्ष रूप से समय बचा सकती है, लेकिन ओटीओएच छोटे प्रकार के साथ संरेखण मुद्दों को अप्रत्यक्ष रूप से समय खर्च कर सकता है।
लेफ्टरेंबाउट

16

बेशक, ऐसे मामले हैं जहां यह उपयोग करना बेहतर है uintया shortया Int16। जब आप जानते हैं कि आपकी डेटा सीमा उस चर प्रकार की बाधाओं के भीतर फिट होगी, तो उस प्रकार का उपयोग करना ठीक है।

स्मृति विवश वातावरण में या बड़ी मात्रा में वस्तुओं के साथ काम करते समय, यह सबसे छोटे आकार के चर का उपयोग करने के लिए समझ में आता है। उदाहरण के लिए, intएस बनाम shortएस के एक लाख तत्व सरणी के आकार में एक महत्वपूर्ण अंतर है ।

अक्सर, जो निम्न में से एक या अधिक कारणों से वास्तविक कोड में नहीं होता है:

  • समय से पहले डेटा की कमी का पता नहीं चला
  • एक मौका था कि डेटा की कमी ठोस नहीं थी या संभावित रूप से परिवर्तित होने के लिए जाने जाते थे
  • व्यापक डेटा श्रेणी के साथ फ़ंक्शन को फिर से उपयोग करने की उम्मीद थी
  • डेवलपर ने बाधाओं के माध्यम से सोचने का समय नहीं लिया
  • मेमोरी की बचत छोटे चर प्रकार का उपयोग करने के लिए उचित नहीं थी

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


8

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

किसी भी डेटा प्रकार का उपयोग करने की तुलना Int32में छोटा समय केवल उसी समय होता है जब कॉम्पैक्ट स्टोरेज या परिवहन के लिए चीजों को पैकिंग या अनपैक करना आवश्यक हो। यदि किसी को आधा बिलियन पॉजिटिव नंबर स्टोर करने की आवश्यकता है, और वे सभी 0 से 100 की सीमा में होंगे, तो प्रत्येक बाइट का उपयोग करके चार के बजाय 1.5 गीगाबाइट स्टोरेज की बचत होगी। यह एक बड़ी बचत है। यदि कोड के एक टुकड़े को कुल दो सौ मूल्यों को संग्रहीत करने की आवश्यकता होती है, हालांकि, उनमें से प्रत्येक को चार के बजाय एक बाइट बनाने से लगभग 600 बाइट्स बचेंगे। शायद परेशान करने लायक नहीं।

अहस्ताक्षरित प्रकारों के संबंध में, केवल वे वास्तव में उपयोगी होते हैं जब सूचना इंटरचेंज प्रदर्शन करते हैं, या जब टुकड़ों में उप-विभाजित करते हैं। यदि, उदाहरण के लिए, किसी को 96-बिट पूर्णांकों पर गणित करने की आवश्यकता है, तो हस्ताक्षरित पूर्णांकों के समूहों की तुलना में तीन अहस्ताक्षरित 32 बिट पूर्णांकों के समूहों पर संगणना करना बहुत आसान होगा। अन्यथा, ऐसी बहुत सारी स्थितियाँ नहीं हैं जहाँ हस्ताक्षरित 32- या 64-बिट मान की सीमा अपर्याप्त होगी, लेकिन समान आकार का मान पर्याप्त होगा।


4

यह आमतौर पर अहस्ताक्षरित प्रकारों का उपयोग करने के लिए एक बुरा विचार है क्योंकि वे अप्रिय तरीकों से बह जाते हैं। x = 5-6आपके कोड में अचानक एक टाइमबॉम्ब है। इस बीच अहस्ताक्षरित प्रकारों के लाभ एक अतिरिक्त अतिरिक्त बिट को उबालते हैं, और यदि वह बिट आपके लिए लायक है, तो आपको इसके बजाय लगभग निश्चित रूप से एक बड़े प्रकार का उपयोग करना चाहिए।

ऐसे मामलों का उपयोग किया जाता है जहां एक छोटा प्रकार समझ में आता है, लेकिन जब तक आप मेमोरी उपयोग के बारे में चिंतित नहीं होते हैं या ट्रांसमिशन या कैश दक्षता या किसी अन्य चिंता के लिए डेटा पैक करने की आवश्यकता होती है, तो आमतौर पर यह मामला है कि छोटे प्रकार का उपयोग करने का कोई लाभ नहीं है । इसके अलावा, कई आर्किटेक्चर पर, यह वास्तव में इन प्रकारों का उपयोग करने के लिए धीमा है ताकि वे वास्तव में एक छोटी लागत लगा सकें।


3
सी में, हस्ताक्षरित ओवरफ्लो अहस्ताक्षरित ओवरफ्लो से भी बदतर है (क्योंकि यह अपरिभाषित व्यवहार है, जबकि अहस्ताक्षरित को ओडोमीटर की तरह रोल करने के लिए निर्दिष्ट किया जाता है)। OTOH, हस्ताक्षरित / अंडरफ्लो, अहस्ताक्षरित अंडरफ्लो की तुलना में बहुत कम आम है।
केविन

सच है, लेकिन हस्ताक्षरित अतिप्रवाह आमतौर पर अधिक स्पष्ट और अनुमानित है।
जैक एडले

मैं आम तौर पर सहमत हूं, लेकिन आपको जागरूक होने की जरूरत है, उदाहरण के लिए, आधुनिक संकलक यदि अन्य हस्ताक्षरित व्यवहार की पूरी मेजबानी के साथ, हस्ताक्षरित हैं, तो उसमें अनुकूलन i+1>iकर सकते हैं। अहस्ताक्षरित अतिप्रवाह एक कोने के मामले में बग पैदा कर सकता है। हस्ताक्षरित अतिप्रवाह आपके पूरे कार्यक्रम को अर्थहीन बना सकता है1i
केविन

@ जेकएडली मुझे पूरा यकीन है कि आप जो कहते हैं उसका कोई मतलब नहीं है, क्योंकि 5-6 एक ही बिट पैटर्न देता है, भले ही इसका अहस्ताक्षरित हो या न हो।
इंगो

@Ingo: आप कितनी बार बिट पैटर्न देखते हैं? क्या मायने रखता है बिट पैटर्न का अर्थ है कि कौन से बिट्स चालू या बंद नहीं हैं।
जैक एडले

2

अक्सर अपने प्रश्न के लिए भूल जाते हैं और संभवतः विशेष रूप से .NET प्रकार के साथ काम करते समय अपने प्रश्न के लिए, सीएलएस अनुपालन है । .NET फ्रेमवर्क पर निर्मित सभी भाषाओं के लिए सभी प्रकार उपलब्ध नहीं हैं।

यदि आप C # के अलावा अन्य भाषाओं द्वारा उपभोग किए जाने वाले कोड लिख रहे हैं और चाहते हैं कि कोड को अधिक से अधिक .NET भाषाओं के साथ इंटरप्रेट करने की गारंटी दी जाए, तो आपको अपने टाइप का उपयोग उन लोगों के लिए प्रतिबंधित करना होगा जो CLS Compliant हैं।

उदाहरण के लिए, VB.NET (7.0 और 7.1) के शुरुआती संस्करणों ने अहस्ताक्षरित पूर्णांक ( UInteger) का समर्थन नहीं किया :

http://msdn.microsoft.com/en-us/library/aa903459(v=vs.71).aspx

अहस्ताक्षरित पूर्णांक सीएलएस के अनुरूप नहीं हैं और इसलिए इसका उपयोग सावधानी से किया जाना चाहिए यदि आप अनिश्चित हैं कि आपका क्लास लाइब्रेरी उपभोक्ता कौन होगा।

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