2014-10-15 7 views
8

इस दिलचस्प सवाल के आधार पर घटाने:uint और पूर्णांक और निरंतर तह

पर विचार करें: Addition of int and uint और के रूप में Nicholas Carey'sanswer में उल्लेख किया निरंतर तह के साथ चारों ओर toying, मैं संकलक का एक उचित रूप में असंगत व्यवहार पर ठोकर खाई गए कोड स्निपेट निम्नलिखित:

int i = 1; 
uint j = 2; 
var k = i - j; 

यहाँ संकलक सही ढंग से करने के लिए longk हल करता है। यह विशेष व्यवहार विनिर्देशों में अच्छी तरह से परिभाषित किया गया है जैसा कि पहले निर्दिष्ट प्रश्न के उत्तर में बताया गया है।

क्या मेरे लिए आश्चर्य की बात थी, कि व्यवहार बदल जाता है जब शाब्दिक स्थिरांक या स्थिरांक सामान्य रूप में साथ काम कर रहा है। पढ़ना निकोलस केरी answer मैंने महसूस किया कि व्यवहार असंगत तो मैं जाँच की और यकीन है कि पर्याप्त हो सकता है:

const int i = 1; 
const uint j = 2; 
var k = i - j; //Compile time error: The operation overflows at compile time in checked mode. 
k = 1 - 2u; //Compile time error: The operation overflows at compile time in checked mode. 

k इस मामले में Uint32 का संकल्प लिया है।

वहाँ व्यवहार भिन्न किया जा रहा है जब स्थिरांक के साथ काम कर या इस एक छोटी लेकिन दुर्भाग्यपूर्ण "बग" (एक बेहतर शब्द की कमी) संकलक में है के लिए एक कारण है?

+2

अनुमान में, कंपाइलर स्थिरांक के लिए निहित रूपांतरण नहीं करता है। – Powerlord

+0

@ पावरलोर्ड वैसे इसे ठीक है, * यह * * int' से 'uint' को स्पष्ट रूप से परिवर्तित कर रहा है। – InBetween

+1

spec इसके लिए अनुमति देता है, यद्यपि ... §6.1.9 लागू निरंतर अभिव्यक्ति रूपांतरण: "प्रकार int की एक निरंतर अभिव्यक्ति (§7.19) प्रकार 'sbyte',' बाइट', 'लघु', ' ushort', 'uint', या 'ulong', बशर्ते निरंतर अभिव्यक्ति का मान गंतव्य प्रकार की सीमा के भीतर है।" अभी भी अक्षर और/या निरंतर चर के लिए यह कहने का प्रयास कर रहा है। – Powerlord

उत्तर

3

इस जवाब here

समस्या चेक बाहर है कि आप स्थिरांक का उपयोग कर रहे है।

रन समय पर जब एक कॉन्स्ट होता है तो व्यवहार सचमुच शाब्दिक के साथ होता है, या जैसे कि आपने कोड में उन संख्याओं को आसानी से कोड किया था, इसलिए संख्या 1 और 2 है क्योंकि यह 1 से 2 के बाद Uint32 पर जाती है uint32 की सीमा के भीतर। फिर जब आप uint32 के साथ 1 - 2 को घटाने का प्रयास करते हैं तो यह 1u - 2u = +4,294,967,295 (0xFFFFFFFF) से बहता है।

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

एक हस्ताक्षरित int श्रेणी -2,147,483,648 (0x80000000) से +2,147,483,647 (0x7FFFFFFF) तक है।

एक हस्ताक्षरित int 0 (0x00000000) से +4,294,967,295 (0xFFFFFFFF) तक है।

कहानी का नैतिक, कॉन्स्ट और var मिश्रण करते समय सावधान रहें, आपको ऐसा कुछ मिल सकता है जिसकी आप अपेक्षा नहीं करते हैं।

+0

दाएं, डरप, समस्या 'var' के साथ है, निरंतर नहीं। कल्पना के माध्यम से गलत रास्ते पर जाने के लिए एक चॉकलेट। 'Var' का उपयोग करके – Powerlord

+0

समस्या नहीं है क्योंकि यह एक संकलित समय त्रुटि है। वास्तविक कोड में मैं कभी भी एक अभिव्यक्ति में 'var' का उपयोग नहीं करूंगा जहां पहली नज़र में प्रकार क्रिस्टल स्पष्ट नहीं है। और मुझे पता है कि 'const' या * निरंतर अक्षरों का उपयोग * एक ही व्यवहार होगा। मेरा सवाल है * क्यों * वह व्यवहार सामान्य के साथ असंगत है जहां चर शामिल हैं। – InBetween

+0

@ पावरलोर्ड संख्या, 'var' समस्या नहीं है। 'लंबा के = 1 - 2u; 'एक संकलन समय त्रुटि भी है। सी # में रिटर्न प्रकार ओवरलोड रिज़ॉल्यूशन में कभी भी भूमिका निभाता नहीं है, इसलिए 'var' इस मुद्दे का हिस्सा क्यों होगा?समस्या यह है कि * स्थिरता * से निपटने के दौरान '1 - 2u'' uint' को हल कर रहा है। – InBetween

4

C# specification version 5 से, खंड 6.1.9, लगातार भाव केवल निम्न अंतर्निहित रूपांतरण

6.1.9 अंतर्निहित निरंतर अभिव्यक्ति की अनुमति से रूपांतरण
एक अंतर्निहित निरंतर अभिव्यक्ति रूपांतरण निम्नलिखित रूपांतरण की अनुमति देता है:
* एक निरंतर अभिव्यक्ति (§7।19) प्रकार int की टाइप करने के लिए sbyte, byte, short, ushort, uint, या ulong, निरंतर अभिव्यक्ति के मूल्य प्रदान की गंतव्य प्रकार की रेंज में है परिवर्तित किया जा सकता है।
• प्रकार long की निरंतर अभिव्यक्ति को ulong में परिवर्तित किया जा सकता है, बशर्ते निरंतर अभिव्यक्ति का मान नकारात्मक न हो।

ध्यान दें कि longint रूपांतरणों की सूची में नहीं है।

(धारा से 7.3.6.2 बाइनरी संख्यात्मक पदोन्नति):

  • या तो संकार्य है

    दूसरे आधे समस्या यह है कि केवल संख्यात्मक प्रोन्नति की एक छोटी संख्या द्विआधारी कार्यों के लिए होता है दशमलव टाइप करने के लिए, अन्य ऑपरेंड को दशमलव प्रकार में परिवर्तित किया जाता है, या बाध्यकारी-समय त्रुटि तब होती है जब अन्य ऑपरेंड प्रकार फ्लोट या डबल होता है।

  • अन्यथा, यदि ऑपरेंड डबल प्रकार का है, तो अन्य ऑपरेंड को डबल टाइप में परिवर्तित कर दिया जाता है।
  • अन्यथा, यदि ऑपरेंड फ्लोट प्रकार का है, तो अन्य ऑपरेंड को फ्लोट प्रकार में परिवर्तित कर दिया जाता है।
  • अन्यथा, यदि ऑपरेंड उलंग प्रकार का होता है, तो अन्य ऑपरेंड को उलंग टाइप करने के लिए परिवर्तित किया जाता है, या बाध्यकारी-समय त्रुटि तब होती है जब अन्य ऑपरेंड प्रकार sbyte, छोटा, int, या लंबा होता है।
  • अन्यथा, यदि या तो ऑपरेंड लंबे प्रकार का है, तो अन्य ऑपरेंड को लंबे समय तक परिवर्तित कर दिया जाता है।
  • अन्यथा, यदि या तो ऑपरेंड यूंट का प्रकार है और अन्य ऑपरेंड प्रकार sbyte, छोटा, या int प्रकार है, तो दोनों ऑपरेंड लंबे प्रकार में परिवर्तित हो जाते हैं।
  • अन्यथा, यदि या तो ऑपरेंड यूंट प्रकार है, तो अन्य ऑपरेंड को यूंट टाइप करने के लिए परिवर्तित किया जाता है।
  • अन्यथा, दोनों ऑपरेटरों को टाइप int में परिवर्तित कर दिया जाता है।

याद: intlong करने के लिए रूपांतरण स्थिरांक के लिए मना किया है, जिसका अर्थ है कि दोनों आर्ग बजाय uint रों करने के लिए प्रोत्साहित कर रहे हैं।

+0

संयोग से, इस बात का कोई संकेत नहीं है कि क्यों 'int' निरंतर अभिव्यक्तियों को' लंबे समय तक परिवर्तित नहीं किया जा सकता ... या किसी भी चर्चा के बारे में कोई चर्चा हो सकती है कि 'uint' स्थिरांक को परिवर्तित किया जा सकता है ... और कोई स्पष्टीकरण क्यों नहीं इन मामलों में से। – Powerlord

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