क्या पूर्णांक का उपयोग डेटा प्रकार के रूप में बहुत अधिक किया जाता है?


9

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

कुछ इस तरह कोड के बारे में थोड़ा भयानक लगता है

TStuffRec = record
   recordID : Integer;
   thingID : Integer;
   otherThingID : Integer;
end;

जब यह लिखा जा सकता है

TStuffRec = record
   recordID : Cardinal;
   thingID : Cardinal;
   otherThingID : Cardinal;
end;

कार्यात्मक रूप से, ये रिकॉर्ड लगभग हमेशा समान होते हैं (और उम्मीद है कि 64-बिट डेल्फी में भी यही काम जारी रहेगा)। लेकिन बहुत बड़ी संख्या में रूपांतरण मुद्दे होंगे।

लेकिन अहस्ताक्षरित ints का उपयोग करने के लिए कमियां भी हैं। मुख्य रूप से यह कहना कि दोनों को मिलाना कितना कष्टप्रद है।

असली सवाल यह है कि क्या यह एक ऐसी चीज है जिसके बारे में वास्तव में सोचा जाता है या सर्वोत्तम प्रथाओं में शामिल किया जाता है? क्या यह आमतौर पर सिर्फ डेवलपर तक है?


5
पीटर, क्या आप डेल्फी-विशिष्ट उत्तरों की तलाश कर रहे हैं?
एडम लीयर

3
@ एना समझना यह है कि डेल्फी डेटाटिप्स कैसे काम करता है एक सबसे उत्कृष्ट उत्तर के लिए। मुझे पूरा यकीन है कि सी प्रोग्रामर इस सवाल का जवाब दे सकते हैं और जवाब दे सकते हैं।
पीटर टर्नर

जवाबों:


9

एक कारण है कि मैं डेल्फी में सभी के बिना अहस्ताक्षरित पूर्णांक प्रकारों का उपयोग नहीं करता हूं, यह है कि हस्ताक्षरित पूर्णांक के साथ मिश्रित होने पर वे समस्याएं पैदा कर सकते हैं। यहाँ एक बार मुझे एक बिट है:

for i := 0 to List.Count - 1 do
  //do something here

मैंने iएक अहस्ताक्षरित पूर्णांक के रूप में घोषित किया था , (आखिरकार, यह एक सूची में एक सूची है जो 0 से शुरू होती है, इसे कभी भी नकारात्मक, सही नहीं होना चाहिए?), लेकिन जब List.Count0 था, तो यह अपेक्षित रूप से लूप को शॉर्ट-सर्किट नहीं करेगा क्योंकि 0 - 1वास्तव में उच्च सकारात्मक संख्या का मूल्यांकन करता है। ऊप्स!

हस्ताक्षर किए गए और अहस्ताक्षरित पूर्णांक, और श्रेणी के मुद्दों को मिलाने में निहित संभावित सुरक्षा समस्याओं के बीच, (यदि आप सकारात्मक संख्याओं से बड़े होने की आवश्यकता है high(signed whatever), तो यह काफी संभावना है कि आप सकारात्मक संख्याओं को high(unsigned whatever)भी बड़ी संख्या में समाप्त कर लेंगे , इसलिए आगे बढ़ना एक ही आकार के अहस्ताक्षरित पर हस्ताक्षर किए जाने से स्विच करने के बजाय अगले बड़े आकार तक आमतौर पर सही कार्रवाई होती है), मैंने वास्तव में अहस्ताक्षरित पूर्णांकों के लिए बहुत अधिक उपयोगों को नहीं पाया है जब अधिकांश डेटा का प्रतिनिधित्व करते हैं।


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

@ चेतावनी: डेल्फी में नहीं। (कम से कम तब तक नहीं जब तक कि आप कुछ ऐसा न करें कि बिल्ट-इन ओवरफ्लो चेकिंग को अक्षम कर दें।) अनंत लूप के बजाय काउंटर ओवरफ्लो होने पर आप एक अपवाद के साथ समाप्त हो जाएंगे। यह अभी भी एक बग है, लेकिन इसे ट्रैक करना बहुत आसान है।
मेसन व्हीलर

अगर तुम कहते हो तो। मैंने हमेशा डेल्फी में ओवरफ्लो चेकिंग को अक्षम किया; हैश कोड और चेकसम जैसी चीजों से झूठी सकारात्मकता के साथ अंतहीन बमबारी करने के बाद, मैंने पूरी तरह से उस "सुविधा" को छोड़ दिया। लेकिन मुझे लगता है कि आप सही हैं, यह उस विशिष्ट त्रुटि को पकड़ा होगा।
Aaronaught

@ चेतावनी: हाँ, आप इसे हैश कोड और चेकसम जैसे सामान के लिए अक्षम करना चाहते हैं जो विशेष रूप से अतिप्रवाह और चारों ओर लपेटने के लिए डिज़ाइन किए गए हैं। लेकिन सामान्य-प्रयोजन गणनाओं के लिए जिन्हें अतिप्रवाह और चारों ओर लपेटने के लिए डिज़ाइन नहीं किया गया है, यह एक महत्वपूर्ण सुरक्षा विशेषता है और इसे बंद करना बिना सीट बेल्ट के ड्राइविंग की तरह है।
मेसन व्हीलर

शायद आप भूल गए हैं, लेकिन डेल्फी के पुराने संस्करणों में अतिप्रवाह जाँच और संकलक निर्देश अविश्वसनीय रूप से छोटी गाड़ी थे। मैं एक डिबगर को सीधे {$ O -} / {$ O +} ब्लॉक के बीच में सीधे तौर पर ओवरफ्लो रिपोर्ट करने के लिए देखने के बाद कई मौकों पर अपने बालों को फाड़कर अलग-अलग याद कर सकता हूं। थोड़ी देर के बाद मैं इसे और नहीं ले सका और इसे विश्व स्तर पर अक्षम कर दिया। फिर, हाँ, यह इस मुद्दे को पकड़ा होगा, लेकिन मुझे अभी भी नहीं लगता कि यह झूठी सकारात्मक की संख्या के लायक है। प्रत्येक अपने स्वयं के लिए, बिल्कुल!
एरॉन

3

ईमानदार होने के लिए मैं आदत से इंटिजर्स का उपयोग करता हूं। मुझे इस तथ्य की आदत हो गई है कि वे ज्यादातर स्थितियों के लिए बड़ी रेंज प्रदान करते हैं और नकारात्मक मूल्यों (जैसे -1) की अनुमति देते हैं। दरअसल, कई बार बाइट्स / शब्द / शोर्ट का उपयोग करना अधिक उचित होगा। अब इसके बारे में सोचकर मैं इन धब्बों पर ध्यान केंद्रित कर सकता हूँ:

  • परिप्रेक्ष्य। टिलेमैप का आकार 192x192 टाइल तक सीमित है, इसलिए मैं टाइल और लूप को संबोधित करने के लिए बाइट का उपयोग कर सकता हूं। लेकिन अगर मानचित्र का आकार बढ़ाया जाए तो मुझे हर उपयोग से गुजरना होगा और इसे प्रतिस्थापित करना होगा जैसे कि शब्द। जब मुझे ऑफ-मैप ऑब्जेक्ट की अनुमति देने की आवश्यकता होती है, तो मुझे स्मॉलिंट में बदलने के लिए फिर से जाना होगा।

  • लूप्स। अक्सर ऐसा होता है कि मैं एक लूप लिखता हूं "i: = 0 से काउंट -1," क्या होता है अगर "i" बाइट है और काउंट = 0 है तो लूप 0 से 255 तक चलता है। ऐसा नहीं है कि मैं यह चाहूंगा।

  • Uniforming। यह याद रखना आसान है और "var i: पूर्णांक;" प्रत्येक मामले में रुकने और "एचएम .." सोचने के लिए, यहां हम 0..120 रेंज के साथ काम कर रहे हैं .. बाइट .. नहीं, रुको, हमें अनइंस्टॉलिज्ड के लिए -1 की आवश्यकता हो सकती है .. शॉर्टिंट .. रुको .. क्या होगा अगर 128। पर्याप्त नहीं है .. अरघ! " या "यह इस जगह में छोटा क्यों है, छोटा नहीं है?"

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

  • -1। यहां तक ​​कि जब मान 0..n-1 सीमा पर होते हैं, तो मुझे अक्सर "कोई मूल्य / अज्ञात / असिंचित / खाली" मान सेट करने की आवश्यकता नहीं होती है, जो सामान्य अभ्यास -1 द्वारा होता है।

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

PS मैं अन्य प्रकारों का उपयोग कब करूं?

  • काउंटर्स, वे कभी भी नकारात्मक नहीं होते हैं और केवल अपनी कक्षा के बाहर ही पढ़े जाते हैं।
  • प्रदर्शन / मेमोरी कारणों, कुछ स्थानों पर छोटे डेटा प्रकारों का उपयोग करने के लिए मजबूर करना।

1

सबसे अच्छा अभ्यास एक डेटा प्रकार का उपयोग करना है जो उपयोग किए जा रहे डेटा (अपेक्षित डेटा) के लिए आवश्यकताओं को फिट बैठता है।

C # उदाहरण: अगर मुझे केवल 0 से 255 का समर्थन करने की आवश्यकता है, तो मैं एक बाइट का उपयोग करूंगा।

अगर मुझे 1,000,000 नकारात्मक और सकारात्मक समर्थन की आवश्यकता है, तो int।

4.2 बिलियन से बड़ा, फिर एक लंबा उपयोग करें।

सही प्रकार का चयन करके, प्रोग्राम अधिकतम मात्रा में मेमोरी का उपयोग करेगा और साथ ही विभिन्न प्रकार के मेमोरी की विभिन्न मात्राओं का उपयोग करेगा।

यहाँ MSDN से एक C # int संदर्भ है।

int 
 -2,147,483,648 to 2,147,483,647
 Signed 32-bit integer

uint 
 0 to 4,294,967,295
 Unsigned 32-bit integer

long 
 -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
 Signed 64-bit integer

ulong 
 0 to 18,446,744,073,709,551,615
 Unsigned 64-bit integer

C # (या सामान्य रूप से .net) में लंबी और उल्टी 128-बिट मशीन पर 128 बिट्स बन जाएगी? क्योंकि डेल्फी में, Integerडेटाटाइप 32-बिट मशीन पर 32 बिट्स है और जाहिरा तौर पर 64-बिट मशीन पर 64 बिट्स होगा।
पीटर टर्नर

1
@Peter टर्नर: नहीं, C # intमें केवल एक शॉर्टहैंड है System.Int32, इसके लिए कोई फर्क नहीं पड़ता कि कोड किस मशीन पर चलता है।
निकी

@ मिक्की, क्या यह type int System.Int32उस प्रभाव की तरह है या कुछ और है? क्या इसे आसानी से फ्रेमवर्क के भविष्य के संस्करण में बदला जा सकता है?
पीटर टर्नर

@ पेटर टर्नर / निक्की (साइज़ोफ़ (int) .ToString ()); ==> 4 लौटाता है (sizeof (Int64) .ToString ()); ==> मेरे 64 बिट विंडोज ओएस पर 8 लौटाता है। Nikie, आँकड़े के रूप में, एक int वास्तव में सिर्फ और Int32 है।
जॉन रेन्नोर

1
टिप्पणी करने के लिए एक बात है कि वहाँ नहीं सभी प्रकार के संगत हैं के साथ आम भाषा विशिष्टताuintइस तरह के गैर-अनुपालन प्रकारों में से एक है, जिसका अर्थ है कि सार्वजनिक रूप से उजागर एपीआई में इसका उपयोग नहीं किया जाना चाहिए। पुस्तकालय में लिखे जाने के अलावा अन्य .NET भाषाओं में उस एपीआई का उपयोग करने की क्षमता को तोड़ने से बचने के लिए। API स्वयं उपयोग कर रहा है intकि uintवह कहां करेगा।
एडम लीयर

1

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

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

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

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