2012-11-25 18 views
7

डी में पूर्णांक ओवरफ़्लो का पता लगाने के लिए कैसे? (जाँच झंडा कैरी?)पूर्णांक ओवरफ़्लो का पता लगाना

मूल उदाहरण:

ubyte a = 100; 
ubyte b = 200; 
ubyte c = a + b; 
// c can't represent 300; how to detect the overflow now? 

संशोधित उदाहरण:

uint a = 2_000_000_000; 
uint b = 3_000_000_000; 
uint c = a + b; 
// c can't represent 5_000_000_000; how to detect the overflow now? 
इसके अलावा गुणा और पूर्व/उत्तर वेतन वृद्धि के साथ

+2

सी ++ http: //stackoverflow.com/questions/199333/best-way-to-detect-integer-overflow-in-cc –

+1

और असेंबली http://stackoverflow.com/ के लिए एक ही प्रश्न देखें प्रश्न/3 9 25528/x86-assembly-inc-and-dec-instruct-and-overflow-flag –

उत्तर

5

आप यह बहुत आसानी से देख सकते कुछ इनलाइन विधानसभा के साथ:

asm { jo overflowed; } // for checking signed types 
// or 
asm { jc overflowed; } // use this for checking unsigned types 

/* continue going */ 

return; 

overflowed: 

/* do whatever to handle it */ 

नोट: आप शायद एक समारोह में यह नहीं डाल सकते क्योंकि फ़ंक्शन कॉल ध्वज रीसेट कर सकते हैं। आप सही संचालन में आपकी रुचि है के बाद इनलाइन यह डाल करने के लिए चाहता हूँ

यह एक प्रकार अतिप्रवाह पर फेंकने के लिए अधिक भार ऑपरेटर का उपयोग करता है बनाने के लिए संभव है:। http://arsdnet.net/dcode/ranged.d एक उदाहरण है। या मुझे लगता है कि मॉड्यूल मानक पुस्तकालय में std.bigint है जो एक मनमाने ढंग से बड़े पूर्णांक प्रकार की पेशकश करके अतिप्रवाह से बचाता है।

+0

'jo' - * कूद ओवरफ्लो *? यह बिल्कुल वैसा ही दिखता है जो मुझे चाहिए था। –

+4

हां ... हालांकि ध्यान दें कि अतिप्रवाह असफलताओं पर वास्तव में नहीं होता है।-1: 11111111 के बाइनरी प्रतिनिधित्व पर विचार करें (ब्रेवटी के लिए यहां यूबेट का उपयोग करके)। यह 255 जैसा ही है। लेकिन प्रोसेसर को पता नहीं है या किस प्रकार पर हस्ताक्षर किया गया है या नहीं, यह सिर्फ संख्या देखता है। 255 + 1 == -1 + 1 == 0. तो वह ले जाने वाला ध्वज सेट करेगा, लेकिन अतिप्रवाह ध्वज नहीं। इसलिए यदि आप विशेष रूप से हस्ताक्षरित संख्याओं का उपयोग कर रहे हैं, तो आप जेसी निर्देश चाहते हैं - अगर ले जाएं तो कूदें - इसके बजाए। –

+2

एक और संभावित गॉचा है वृद्धि वृद्धि निर्देश * नहीं * ले जाने वाला ध्वज सेट करता है .... और संकलक एक + = 1 को इंक में अनुकूलित करेगा यदि किसी को संकलन समय पर जाना जाता है। तो आप एक + बी के लिए ठीक हैं, क्योंकि वे रनटाइम हैं, लेकिन एक + = 1 या ए ++ एएसएम चेक पर एक आश्चर्यजनक पास दे सकता है। –

8

स्टार्टर्स के लिए, आपके द्वारा दिया गया कोड भी संकलित नहीं होगा, क्योंकि int से छोटे आकार वाले सभी पूर्णांक गणित int के साथ किए जाते हैं। तो a + b का परिणाम int है, और int स्पष्ट रूप से ubyte में परिवर्तित नहीं होगा, क्योंकि यह एक संकुचित रूपांतरण है। यदि आप इसे c पर असाइन करना चाहते हैं, तो आपको इसे डालना होगा।

ubyte c = cast(ubyte)(a + b); 

अब, यह स्पष्ट रूप से एक अनियंत्रित रूपांतरण है, और यह खुशी से c में 44 सामान पाएंगे (क्योंकि कि 100 और 200 के मूल्यों को देखते हुए कलाकारों का परिणाम है)। एक ConvOverflowException, (जो ConvException का एक उपवर्ग है), क्योंकि परिणाम का अनुरोध प्रकार में फिट नहीं हो

ubyte c = to!ubyte(a + b); 

फेंक देते हैं कि: यदि आप एक जाँच की रूपांतरण चाहते हैं, तो std.conv.to का उपयोग करें।

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

+0

'add' जैसे intrinsics जोड़ने के बारे में, जो अतिप्रवाह बिट भी वापस लौटाता है? – Mehrdad

+0

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

+0

उदाहरण कोड मेरे प्रश्न को स्पष्ट करने के लिए सिर्फ एक नकली है। अपने अवकाश पर 'यूट' के साथ 'ubyte' को बदलें। –

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