बाइट + बाइट = int ... क्यों?


365

इस C # कोड को देखते हुए:

byte x = 1;
byte y = 2;
byte z = x + y; // ERROR: Cannot implicitly convert type 'int' to 'byte'

byte(या short) प्रकारों पर किए गए किसी भी गणित के परिणाम को संक्षेप में एक पूर्णांक में डाल दिया जाता है। इसका परिणाम स्पष्ट रूप से परिणाम को बाइट में डालना है:

byte z = (byte)(x + y); // this works

मैं क्या सोच रहा हूँ क्यों? क्या यह वास्तु है? दार्शनिक?

हमारे पास है:

  • int+ int=int
  • long+ long=long
  • float+ float=float
  • double+ double=double

तो क्यों नहीं:

  • byte+ byte=byte
  • short+ short= short?

पृष्ठभूमि की एक बिट: मैं "छोटी संख्या" (यानी <8) पर गणना की एक लंबी सूची का प्रदर्शन कर रहा हूं और एक बड़े सरणी में मध्यवर्ती परिणाम संग्रहीत कर रहा हूं। एक का उपयोग करना बाइट सरणी (के बजाय एक पूर्णांक सरणी) तेजी से होता है (क्योंकि कैश हिट फिल्मों में से)। लेकिन कोड के माध्यम से फैली हुई व्यापक बाइट-कास्ट इसे और अधिक अपठनीय बनाती हैं।



10
यह एरिक के मानक का ज्ञान नहीं है जो यहां उपयोगी होगा - यह भाषा के डिजाइन का उसका ज्ञान है ; क्यों नहीं। लेकिन हाँ, एरिक का जवाब बहुत निश्चित होगा :)
जॉन स्कीट

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

28
@ एरिक: यह बाइट के लिए बहुत मायने रखता है, लेकिन शायद शॉर्ट / यूथॉर्ट के लिए उतना समझदारी नहीं है।
जॉन स्कीट

23
@ ईरिक: byte1 | byte2उन्हें संख्या के रूप में मानने में बिलकुल नहीं है। यह उन्हें बिट्स के पैटर्न के रूप में सटीक रूप से व्यवहार कर रहा है। मैं आपकी बात समझता हूं, लेकिन ऐसा सिर्फ इसलिए होता है कि हर बार जब मैंने C # में बाइट्स पर कोई अंकगणित किया, तो मैं वास्तव में उन्हें बिट्स के रूप में मान रहा था, न कि संख्याओं के रूप में, और यह व्यवहार हमेशा से है।
रोमन स्टार्कोव

जवाबों:


228

आपके कोड स्निपेट की तीसरी पंक्ति:

byte z = x + y;

वास्तव में मतलब है

byte z = (int) x + (int) y;

तो, बाइट्स पर कोई + ऑपरेशन नहीं है, बाइट्स को पहले पूर्णांक में डाला जाता है और दो पूर्णांकों को जोड़ने का परिणाम एक (32-बिट) पूर्णांक होता है।


मैंने नीचे कोड की कोशिश की है, लेकिन यह अभी भी काम नहीं कर रहा है। बाइट z = (बाइट) x + (बाइट) y;
बेनामी

10
ऐसा इसलिए है क्योंकि बाइट्स के लिए कोई + ऑपरेशन नहीं है (ऊपर देखें)।
Byte

35
यह सबसे सही, संक्षिप्त उत्तर है। बाइट्स के बीच जोड़ने के लिए कोई ऑपरेंड नहीं है, इसलिए यह समझाने के बजाय कि "दो बाइट्स" जोड़ना काम करता है या नहीं ( ऐसा कभी नहीं हुआ ), यह स्पष्ट रूप से दिखाता है कि परिणाम एक इंट क्यों है, क्योंकि केवल एक चीज जो 2 इन्ट्स के अतिरिक्त है
रिचर्ड द किवी

2
मुझे अन्य सभी उत्तरों (श्री जॉन स्कीट के लिए कोई अपराध नहीं) पढ़ने में चक्कर आ गया। यह मुझे सबसे सरल उत्तर मिला जो हुड के नीचे क्या चल रहा है, इसका सही वर्णन करता है। धन्यवाद!
रियरेनेंग

यहाँ एक उत्तर है जो मैंने कहीं और लिखा है जिसमें पहचानने के लिए एक कार्यक्रम शामिल है कि यह संकलक द्वारा संचालित स्वचालित प्रचार कब हो रहा intहै: stackoverflow.com/a/43578929/4561887
गेब्रियल स्टेपल्स

172

"ऐसा क्यों होता है" के संदर्भ में, यह इसलिए है क्योंकि किसी भी ऑपरेटर ने सी # द्वारा परिभाषित नहीं किया है, बाइट के साथ अंकगणित, लघु, या ushort, जैसा कि दूसरों ने कहा है। यह उत्तर क्यों है उन ऑपरेटरों को परिभाषित नहीं किया जाता है।

मेरा मानना ​​है कि यह मूल रूप से प्रदर्शन के लिए है। प्रोसेसर में 32 बिट्स के साथ अंकगणित करने के लिए देशी ऑपरेशन बहुत जल्दी होते हैं। रूपांतरण को परिणाम से एक बाइट तक स्वचालित रूप से कर सकता है से किया सकता है, लेकिन उस मामले में प्रदर्शन दंड का परिणाम होगा जहां आप वास्तव में उस व्यवहार को नहीं चाहते हैं।

मुझे लगता है कि यह एनोटेट C # मानकों में से एक में उल्लिखित है। जा रहा है ...

संपादित करें: वार्षिक रूप से, मैंने अब एनोटेट CMA # 2 युक्ति, एनोटेट MS C # 3 युक्ति और एनोटेशन CLI युक्ति के माध्यम से देखा है, और उनमें से कोई भी इसका उल्लेख नहीं करता है जहाँ तक मैं देख सकता हूँ। मुझे यकीन है कि मैंने ऊपर दिए गए कारण को देख लिया है, लेकिन मुझे पता है कि अगर मुझे पता है तो मुझे झटका लगेगा। माफी, संदर्भ प्रशंसकों :(


14
मुझे यह कहने के लिए खेद है, लेकिन मुझे यह सबसे अच्छा जवाब नहीं मिला।
वीवीएस

42
क्या आपने हर उस उत्तर को नकार दिया है जो आपको सबसे अच्छा नहीं लगता? ;)
जॉन स्कीट

55
(बस स्पष्ट करने के लिए, मैं वास्तव में आपके पास नहीं जा रहा हूं। ऐसा लगता है कि हर किसी के पास डाउनवोटिंग के लिए अपने स्वयं के मानदंड हैं और यह ठीक है। मैं केवल एक उत्तर को अस्वीकार करता हूं यदि मेरा मानना ​​है कि यह केवल गैर-आदर्श के बजाय सक्रिय रूप से हानिकारक है। )
जॉन स्कीट

21
मैं शीर्ष पर "सर्वश्रेष्ठ" उत्तर प्राप्त करने के लिए एक साधन के रूप में मतदान का उपयोग करता हूं। वास्तव में मैंने पाया कि आपने अपने उत्तर में बहुत कुछ नहीं कहा जो मेरे पतन का मुख्य कारण था। एक और कारण हो सकता है कि मेरी व्यक्तिपरक भावना यह है कि आपका प्रतिनिधि आपको एक बड़ा बोनस देता है जब वह मतदान के लिए आता है और आप "बेहतर" उत्तरों के ऊपर उतर रहे हैं।
VVS

23
शीर्ष करने के लिए "सबसे अच्छा" उत्तर पाने के लिए सबसे अच्छा तरीका IMO है कि उत्थान करना है। ईमानदारी से कहूं तो मुझे लगता है कि सबसे जानकारीपूर्ण जवाब यहाँ प्रश्न में एरिक की टिप्पणी ... लेकिन उसके अलावा, डिजाइन परिप्रेक्ष्य के लिए वहाँ मुझे नहीं लगता कि (के रूप में करने के लिए "क्या संकलक के कर" परिप्रेक्ष्य खिलाफ) है है ज्यादा "प्रदर्शन" से परे जवाब। विशेष रूप से, मैं वास्तव में "इसे अतिप्रवाह को रोकता है" तर्क (17 वोट) नहीं खरीदता क्योंकि यह इंट + इंट = लंबा सुझाव देगा।
जॉन स्कीट

68

मुझे लगा कि मैंने इसे पहले कहीं देखा है। से इस लेख, पुराने नई बात :

मान लीजिए कि हम एक काल्पनिक दुनिया में रहते हैं, जहाँ 'बाइट' के संचालन के परिणामस्वरूप 'बाइट' होती है।

byte b = 32;
byte c = 240;
int i = b + c; // what is i?

इस काल्पनिक दुनिया में, मैं का मूल्य 16 होगा! क्यों? क्योंकि दो ऑपरेटर + ऑपरेटर के लिए दोनों बाइट्स हैं, इसलिए "बी + सी" योग की गणना एक बाइट के रूप में की जाती है, जिसका परिणाम पूर्णांक ओवरफ्लो के कारण 16 होता है। (और, जैसा कि मैंने पहले उल्लेख किया था, पूर्णांक अतिप्रवाह नया सुरक्षा हमला वेक्टर है।)

EDIT : रेमंड बचाव कर रहा है, अनिवार्य रूप से, C और C ++ ने मूल रूप से लिया। टिप्पणियों में, वह इस तथ्य का बचाव करता है कि भाषा के पिछड़ेपन के आधार पर C # समान दृष्टिकोण लेता है।


42
पूर्णांक के साथ अगर हम उन्हें जोड़ते हैं और इसे ओवरफ्लो करते हैं तो यह स्वचालित रूप से एक अलग डेटाटाइप के रूप में नहीं डालती है, हालांकि यह बाइट के साथ क्यों होता है?
रयान

2
Ints के साथ यह अतिप्रवाह करता है। Int जोड़ने की कोशिश करें। MaxValue + 1 आपको 2147483648 के बजाय -2147483648 मिलता है।
डेविड

8
@ Longhorn213: हाँ, यह है कि रयान कह रही है: int गणित अतिप्रवाह कर सकते हैं, लेकिन int गणित लौटे नहीं है।
माइकल पेट्रोत्ता

28
बिल्कुल सही। यदि इसका मतलब सुरक्षा उपाय है, तो यह बहुत खराब तरीके से लागू किया गया है;)
जॉन स्कीट

5
@ रियान: "आलसी" सी # भाषा के डिजाइनरों के खिलाफ बनाने के लिए एक सुंदर भारी शुल्क है, जो कि आदिम गणित के रूप में बुनियादी है। यदि आप उन पर कुछ भी आरोप लगाना चाहते हैं, तो इसे "C / C ++ के साथ अत्यधिक पीछे की संगतता" बनाएं।
माइकल पेत्रोत्ता

58

सी#

ECMA-334 बताता है कि इसके अलावा केवल int + int, uint + uint, long + long और ulong + ulong (ECMA-334 14.7.4) पर कानूनी रूप से परिभाषित किया गया है। जैसे, ये 14.4.2 के संबंध में विचार किए जाने वाले उम्मीदवार हैं। क्योंकि बाइट से लेकर इंट, यूइंट, लॉन्ग और अलॉन्ग तक के निहितार्थ हैं, इसके अलावा सभी फंक्शन मेंबर्स 14.4.2.1 के तहत फंक्शन मेंबर हैं। हमें १४.४.२.३ में नियमों द्वारा सर्वश्रेष्ठ निहित कास्ट ढूंढना है:

कास्टिंग (C1) से इंट (T1) कास्टिंग (C2) से यूइंट (T2) या उलॉन्ग (T2) से बेहतर है क्योंकि:

  • यदि T1 int है और T2 uint है, या ulong है, तो C1 बेहतर रूपांतरण है।

कास्टिंग (C1) से इंट (T1) कास्टिंग (C2) से लेकर लॉन्ग (T2) से बेहतर है क्योंकि इंट से लॉन्ग तक एक निहित कास्ट है:

  • यदि T1 से T2 तक एक अंतर्निहित रूपांतरण मौजूद है, और T2 से T1 तक कोई अंतर्निहित रूपांतरण मौजूद नहीं है, तो C1 बेहतर रूपांतरण है।

इसलिए int + int फ़ंक्शन का उपयोग किया जाता है, जो एक इंट देता है।

जो यह कहने का बहुत लंबा रास्ता है कि यह C # विनिर्देशन में बहुत गहरे दफन है।

CLI

CLI केवल 6 प्रकार (int32, देशी int, int64, F, O, & &) पर संचालित होता है। (ECMA-335 पार्टीशन 3 सेक्शन 1.5)

बाइट (int8) उन प्रकारों में से एक नहीं है, और इसके अतिरिक्त करने से पहले स्वचालित रूप से एक int32 के लिए मजबूर किया जाता है। (ECMA-335 पार्टीशन 3 सेक्शन 1.6)


यह कि ECMA केवल उन विशेष कार्यों को निर्दिष्ट करता है जो किसी भाषा को अन्य नियमों को लागू करने से नहीं रोकेंगे। VB.NET सहायक के लिए अनुमति देगा byte3 = byte1 And byte2एक क्रम अपवाद अगर फेंक होगा एक डाली के बिना, लेकिन unhelpfully int1 = byte1 + byte2पैदावार 255 से अधिक एक मूल्य मैं अगर किसी भी भाषा की अनुमति होगी पता नहीं है byte3 = byte1+byte2और जब कि 255 से अधिक है एक अपवाद फेंक नहीं, बल्कि एक अपवाद है, तो फेंक int1 = byte1+byte2पैदावार 256-510 रेंज में एक मान।
सुपरकैट

26

बाइट्स में कुछ अक्षमता को इंगित करने वाले परिणाम और बाइट को वापस करने के संकेत को गलत बताते हैं। x86 प्रोसेसर में विशेष रूप से 8-बिट मात्रा पर पूर्णांक संचालन के लिए निर्देश हैं।

वास्तव में, x86 / 64 प्रोसेसर के लिए, 32-बिट या 16-बिट ऑपरेशन का प्रदर्शन 64-बिट या 8-बिट संचालन की तुलना में कम कुशल होता है, क्योंकि ऑपरेंड उपसर्ग बाइट को डिकोड करना पड़ता है। 32-बिट मशीनों पर, 16-बिट संचालन का प्रदर्शन समान जुर्माना करता है, लेकिन 8-बिट संचालन के लिए अभी भी समर्पित opcodes हैं।

कई RISC आर्किटेक्चर में समान मूल शब्द / बाइट कुशल निर्देश हैं। जिनके पास आमतौर पर स्टोर-एंड-कन्वर्ट-टू-साइन-वैल्यू-ऑफ-ऑफ-सम-बिट-लंबाई नहीं होती है।

दूसरे शब्दों में, यह निर्णय इस बात पर आधारित होना चाहिए कि बाइट का प्रकार क्या है, हार्डवेयर की अंतर्निहित अक्षमताओं के कारण नहीं।


+1; अगर केवल यह धारणा गलत नहीं होती तो हर बार जब मैं कभी शिफ्ट होता हूं और C # में दो बाइट करता हूं ...
रोमन स्टार्कोव

परिणाम को कम करने के लिए कोई प्रदर्शन लागत नहीं होनी चाहिए। X86 असेंबली में यह रजिस्टर के एक बाइट को कॉपी करने या रजिस्टर से चार बाइट्स के बीच का अंतर है।
जोनाथन एलन

1
@JonathanAllen बिल्कुल। एक ही अंतर है, विडंबना यह है कि व्यापक रूपांतरण करते समय। वर्तमान (या तो हस्ताक्षर किए विस्तार या अहस्ताक्षरित का विस्तार।) डिजाइन निष्पादन दंड को चौड़ा अनुदेश निष्पादित करने के लिए आती
reirab

" बाइट प्रकार क्या है के लिए धारणा " - कि byte(और char) के लिए इस व्यवहार की व्याख्या हो सकती है , लेकिन इसके लिए नहींshort जिसके लिए शब्दार्थ स्पष्ट रूप से एक संख्या नहीं है।
SMLS

13

मुझे याद है कि एक बार जॉन स्कीट से कुछ पढ़ते हुए (अब नहीं मिल सकता है, मैं देखता रहूँगा) कि कैसे बाइट वास्तव में + ऑपरेटर को अधिभार नहीं देता है। वास्तव में, जब आपके नमूने में दो बाइट्स जोड़ते हैं, तो प्रत्येक बाइट को वास्तव में एक इंट में बदल दिया जाता है। उस का परिणाम स्पष्ट रूप से एक int है। अब जब इस तरह से डिजाइन किया गया था, मैं जॉन स्कीट के खुद पोस्ट करने की प्रतीक्षा करूंगा :)

संपादित करें: यह मिल गया! इस बहुत ही विषय के बारे में महान जानकारी यहाँ


9

इसकी वजह ओवरफ्लो और कैरी है।

यदि आप दो 8 बिट संख्या जोड़ते हैं, तो वे 9 वें बिट में ओवरफ्लो कर सकते हैं।

उदाहरण:

  1111 1111
+ 0000 0001
-----------
1 0000 0000

मुझे यकीन है कि के लिए पता नहीं है, लेकिन मुझे लगता है कि मान ints, longsऔर doublesअधिक स्थान दिया जाता है, क्योंकि वे बहुत बड़ी बात है के रूप में कर रहे हैं। इसके अलावा, वे 4 के गुणक हैं, जो कंप्यूटर को संभालने के लिए अधिक कुशल हैं, आंतरिक डेटा बस की चौड़ाई 4 बाइट्स या 32 बिट्स (64 बिट्स अब अधिक प्रचलित हो रही है) के कारण चौड़ी है। बाइट और शॉर्ट थोड़ा अधिक अक्षम हैं, लेकिन वे अंतरिक्ष को बचा सकते हैं।


23
लेकिन बड़े डेटा प्रकार एक ही व्यवहार का पालन नहीं करते हैं।
आईशर

12
अतिप्रवाह के मुद्दे एक तरफ हैं। यदि आप अपना तर्क लेना चाहते थे और इसे भाषा पर लागू करना चाहते थे, तो सभी डेटा प्रकार इसके अलावा अंकगणित के बाद एक बड़ा डेटा प्रकार लौटा देंगे, जो निश्चित रूप से ऐसा नहीं है। int + int = इंट, लंबा + लंबा = लंबा। मुझे लगता है कि सवाल असंगतता के संबंध में है।
जोसेफ

यह मेरा पहला विचार था लेकिन फिर int + int = long क्यों नहीं है? इसलिए मैं "संभव अतिप्रवाह" तर्क नहीं खरीद रहा हूं ... फिर भी <grin>।
रॉबर्ट कार्टेनो

11
ओह, और "संभावित अतिप्रवाह" उत्थान के बारे में, बाइट + बाइट = शॉर्ट क्यों नहीं?
रॉबर्ट कार्टेनो

A) यह काम करने के तरीके को C # के नियमों के अनुसार क्यों करता है? नीचे मेरा जवाब देखें। बी) इसे जिस तरह से डिजाइन किया गया था वह क्यों था? संभवतः सिर्फ प्रयोज्य विचार, जिस तरह से ज्यादातर लोग ints और बाइट्स का उपयोग करते हैं, व्यक्तिपरक निर्णय के आधार पर।
एमकेपी

5

सी # भाषा कल्पना 1.6.7.5 7.2.6.2 बाइनरी न्यूमेरिक प्रमोशन से यह दोनों ऑपरेंड को इंट में बदल देता है अगर यह इसे कई अन्य श्रेणियों में फिट नहीं कर सकता है। मेरा अनुमान है कि वे एक पैरामीटर के रूप में बाइट लेने के लिए + ऑपरेटर को अधिभार नहीं डालते हैं, लेकिन चाहते हैं कि यह कुछ हद तक सामान्य रूप से कार्य करे ताकि वे केवल इंट डेटा प्रकार का उपयोग करें।

सी # भाषा युक्ति


4

मेरे संदेह है कि सी # वास्तव में बुला रहा है है operator+पर परिभाषित int(जो देता है एक intजब तक आप एक में हैं checkedब्लॉक), और परोक्ष अपने दोनों कास्टिंग bytes/ shortsकरने के लिए ints। इसलिए व्यवहार असंगत प्रतीत होता है।


3
यह स्टैक पर दोनों बाइट्स को धकेलता है, फिर इसे "ऐड" कमांड कहता है। आईएल में, दो मूल्यों को "खाती है" और उन्हें एक इंट के साथ बदल देता है।
जोनाथन एलन

3

यह शायद भाषा डिजाइनरों की ओर से एक व्यावहारिक निर्णय था। आखिरकार, एक इंट एक इंट 32 है, एक 32-बिट हस्ताक्षरित पूर्णांक। जब भी आप int से छोटे टाइप पर एक पूर्णांक ऑपरेशन करते हैं, तो यह 32 बिट सीपीयू द्वारा वैसे भी एक 32 साइन किए हुए इंट में परिवर्तित होने वाला है। कि, छोटे पूर्णांकों के ओवरफ्लो होने की संभावना के साथ संयुक्त, शायद सौदे को सील कर दिया। यह आपको ओवर / अंडर-फ्लो के लिए लगातार जाँच के काम से बचाता है, और जब बाइट्स पर एक अभिव्यक्ति का अंतिम परिणाम सीमा में होगा, इस तथ्य के बावजूद कि कुछ मध्यवर्ती चरण में यह सीमा से बाहर होगा, तो आपको एक सही मिलेगा परिणाम।

एक अन्य विचार: इन प्रकारों पर ओवर / अंडर-फ्लो को सिम्युलेटेड करना होगा, क्योंकि यह स्वाभाविक रूप से सबसे अधिक संभावना वाले सीपीयू पर नहीं होगा। क्यों परेशान?


2

यह मेरे उत्तर के अधिकांश भाग के लिए है, जो इस विषय से संबंधित है, यहां एक समान प्रश्न पहले प्रस्तुत किया गया है

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

यदि आप Int16 प्रारूप में परिणाम वापस चाहते हैं, तो यह अप्रासंगिक है यदि आप कोड में कास्ट करते हैं, या संकलक (काल्पनिक रूप से) "हुड के तहत" रूपांतरण का उत्सर्जन करता है।

उदाहरण के लिए, Int16 अंकगणित करने के लिए:

short a = 2, b = 3;

short c = (short) (a + b);

दो संख्याओं का विस्तार 32 बिट्स तक हो जाएगा, जोड़ दिया जाएगा, फिर 16 बिट्स पर वापस कर दिया जाएगा, जो कि एमएस ने इसे कैसे बनाया।

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


1

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


0

मुझे लगता है कि यह डिजाइन में कमी है जिसके बारे में ऑपरेशन अधिक सामान्य था ... अगर बाइट + बाइट = बाइट शायद अधिक लोगों को परेशान किया जाएगा, जब परिणाम के लिए एक इंट की आवश्यकता होती है।


2
मैं एक बार दूसरे तरीके से परेशान हो जाता हूं :) मुझे हमेशा बाइट के परिणाम की आवश्यकता लगती है, इसलिए मुझे हमेशा कास्ट करना पड़ता है।
रोमन स्टार्कोव

सिवाय आपको इंट करने की जरूरत नहीं है। डाली निहित है। केवल दूसरा तरीका स्पष्ट है।
निकी

1
@ मिक्की मुझे लगता है कि आपको मेरा उत्तर समझ में नहीं आया। यदि दो बाइट्स जोड़ने से एक बाइट उत्पन्न होती है, तो ओवरफ्लो को रोकने के लिए किसी को पहले अतिरिक्त जोड़ने के लिए ऑपरेंड (परिणाम नहीं) डालना होगा ।
फोरट्रान

0

.NET फ्रेमवर्क कोड से:

// bytes
private static object AddByte(byte Left, byte Right)
{
    short num = (short) (Left + Right);
    if (num > 0xff)
    {
        return num;
    }
    return (byte) num;
}

// shorts (int16)
private static object AddInt16(short Left, short Right)
{
    int num = Left + Right;
    if ((num <= 0x7fff) && (num >= -32768))
    {
        return (short) num;
    }
    return num;
}

.NET 3.5 और इसके बाद के संस्करण को सरल बनाएं :

public static class Extensions 
{
    public static byte Add(this byte a, byte b)
    {
        return (byte)(a + b);
    }
}

अब आप कर सकते हैं:

byte a = 1, b = 2, c;
c = a.Add(b);


0

मैंने बाइट और इंट के बीच प्रदर्शन का परीक्षण किया है।
अंतर मूल्यों के साथ:

class Program
{
    private int a,b,c,d,e,f;

    public Program()
    {
        a = 1;
        b = 2;
        c = (a + b);
        d = (a - b);
        e = (b / a);
        f = (c * b);
    }

    static void Main(string[] args)
    {
        int max = 10000000;
        DateTime start = DateTime.Now;
        Program[] tab = new Program[max];

        for (int i = 0; i < max; i++)
        {
            tab[i] = new Program();
        }
        DateTime stop = DateTime.Now;

        Debug.WriteLine(stop.Subtract(start).TotalSeconds);
    }
}

बाइट मूल्यों के साथ:

class Program
{
    private byte a,b,c,d,e,f;

    public Program()
    {
        a = 1;
        b = 2;
        c = (byte)(a + b);
        d = (byte)(a - b);
        e = (byte)(b / a);
        f = (byte)(c * b);
    }

    static void Main(string[] args)
    {
        int max = 10000000;
        DateTime start = DateTime.Now;
        Program[] tab = new Program[max];

        for (int i = 0; i < max; i++)
        {
            tab[i] = new Program();
        }
        DateTime stop = DateTime.Now;

        Debug.WriteLine(stop.Subtract(start).TotalSeconds);
    }
}

यहां परिणाम:
बाइट: 3.57s 157mo, 3.71s 171mo, 3.74s 168 सीपीयू के साथ ~ = 30%
int: 4.05s 298mo, 3.92s 278mo, 4.28 294mo CPU के साथ ~ = 27%
निष्कर्ष:
byte CPU का अधिक उपयोग करें लेकिन यह लेस लेस मेमोरी और यह तेज़ है (शायद इसलिए कि आवंटित करने के लिए कम बाइट हैं)


-1

अन्य सभी महान टिप्पणियों के अलावा, मुझे लगा कि मैं एक छोटा सा टिडबिट जोड़ूंगा। बहुत सारी टिप्पणियों ने सोचा है कि int, long, और बहुत अधिक किसी अन्य संख्यात्मक प्रकार भी इस नियम का पालन नहीं करता है ... अंकगणितीय के जवाब में "बड़ा" प्रकार लौटाता है।

बहुत सारे जवाबों को प्रदर्शन के साथ करना पड़ा (अच्छी तरह से, 32 बिट्स 8 बिट्स की तुलना में तेज है)। हकीकत में, एक 8bit संख्या अभी भी 32bit CPU के लिए एक 32bit संख्या है .... भले ही आप दो बाइट्स जोड़ते हों, cpu पर काम करने वाले डेटा का हिस्सा 32 बिट्स की परवाह किए बिना जा रहा है ... इसलिए ints जोड़ना नहीं चल रहा है दो बाइट्स जोड़ने की तुलना में कोई भी "तेज" हो ... इसकी सभी सीपीयू के समान है। अब, दो ints जोड़ना एक 32 बिट प्रोसेसर पर दो लॉन्ग जोड़ने की तुलना में तेज़ होगा, क्योंकि दो लॉन्ग को जोड़ने से अधिक माइक्रोफ़ोन की आवश्यकता होती है क्योंकि आप प्रोसेसर शब्द की तुलना में व्यापक संख्याओं के साथ काम कर रहे हैं।

मुझे लगता है कि बाइट्स में परिणाम के लिए बाइट अंकगणितीय होने का मूल कारण बहुत स्पष्ट और सीधा है: 8 बिट्स बहुत दूर नहीं जाते हैं! : D 8 बिट्स के साथ, आपके पास 0-255 की अहस्ताक्षरित श्रेणी है। ऐसा नहीं है काम करने के लिए कमरे की एक पूरी बहुत कुछ है ... संभावना है कि आप एक बाइट्स सीमाओं में चलाने जा रहे हैं अंकगणित में उनका उपयोग करते समय बहुत अधिक है। हालांकि, मौका है कि आप बिट्स से बाहर निकलने के लिए जा रहे हैं, जब ints, या longs, या डबल्स, आदि के साथ काम करना काफी कम है ... कम पर्याप्त है कि हम शायद ही कभी अधिक की आवश्यकता का सामना करते हैं।

बाइट से इंट में स्वचालित रूपांतरण तार्किक है क्योंकि एक बाइट का पैमाना इतना छोटा है। स्वचालित रूप से लंबे समय तक, स्वचालित रूप से डबल-फ्लोट, आदि में रूपांतरण तार्किक नहीं है क्योंकि उन संख्याओं में महत्वपूर्ण पैमाने हैं।


यह अभी भी स्पष्ट नहीं करता है कि byte - byteरिटर्न क्यों int, या वे क्यों नहीं डाली short...
KthProg

आप घटाव से भिन्न प्रकार लौटाने के लिए क्यों चाहेंगे? यदि byte + byteरिटर्न int, क्योंकि 255 + कुछ भी बाइट की तुलना में अधिक है, तो यह समझ में नहीं आता है कि किसी भी बाइट माइनस के लिए किसी भी अन्य बाइट की वापसी रिटर्न इंटेंसिटी दृष्टिकोण से एक इंट के अलावा कुछ भी नहीं है।
जिरस्टा

मैं ऐसा नहीं करूंगा, यह दर्शाता है कि उपरोक्त कारण शायद सही नहीं है। यदि इसे परिणाम में "फिटिंग" के साथ करना था, तो byteघटाव एक वापस आ जाएगा byte, और बाइट जोड़ एक short( byte+ byteहमेशा फिट होगा short) में वापस आ जाएगा । यदि आप जैसा कहते हैं, यह सुसंगतता के बारे में था, तब shortभी इसके बजाय दोनों कार्यों के लिए पर्याप्त होगा int। स्पष्ट रूप से कारणों का मिश्रण है, उनमें से सभी जरूरी नहीं कि अच्छी तरह से सोचा-समझा हो। या, नीचे दिया गया प्रदर्शन कारण अधिक सटीक हो सकता है।
KthProg
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.