2013-06-26 8 views
10

एक ठेठ निरपेक्ष मूल्य समारोह पर विचार करें (जहां तर्क की खातिर अधिकतम आकार का अभिन्न प्रकार लंबा है):क्या अतिप्रवाह ट्रिगर किए बिना हस्ताक्षरित पूर्णांक के हस्ताक्षरित पूर्ण मूल्य प्राप्त करने का कोई सुरक्षित तरीका है?

unsigned long abs(long input) 
{ 
    if (input >= 0) 
    { 
     // input is positive 
     // We know this is safe, because the maximum positive signed 
     // integer is always less than the maximum positive unsigned one 
     return static_cast<unsigned long>(input); 
    } 
    else 
    { 
     return static_cast<unsigned long>(-input); // ut oh... 
    } 
} 

यह:

unsigned long abs(long input); 

इस का एक अनुभवहीन कार्यान्वयन की तरह कुछ लग सकता है कोड अपरिभाषित व्यवहार को ट्रिगर करता है, क्योंकि input की अस्वीकृति अतिप्रवाह हो सकती है, और हस्ताक्षरित पूर्णांक ओवरफ़्लो ट्रिगर करना अपरिभाषित व्यवहार है। उदाहरण के लिए, 2 एस पूरक मशीनों पर, std::numeric_limits<long>::min() का पूर्ण मूल्य std::numeric_limits<long>::max() से 1 बड़ा होगा।

लाइब्रेरी लेखक इस समस्या के आसपास काम करने के लिए क्या कर सकता है?

उत्तर

16

कोई पहले हस्ताक्षरित संस्करण पर जा सकता है। यह अच्छी तरह से परिभाषित व्यवहार प्रदान करता है। यदि इसके बजाए, कोड इस तरह दिखता है:

unsigned long abs(long input) 
{ 
    if (input >= 0) 
    { 
     // input is positive 
     return static_cast<unsigned long>(input); 
    } 
    else 
    { 
     return -static_cast<unsigned long>(input); // read on... 
    } 
} 

हम दो अच्छी तरह से परिभाषित संचालन का आह्वान करते हैं। अहस्ताक्षरित एक के लिए परिवर्तित हस्ताक्षर किए पूर्णांक अच्छी तरह से N3485 4.7 [conv.integral] द्वारा परिभाषित किया गया है/2:

तो गंतव्य प्रकार अहस्ताक्षरित है, जिसके परिणामस्वरूप मूल्य कम से कम अहस्ताक्षरित पूर्णांक स्रोत पूर्णांक तक अनुकूल (सापेक्ष है 2^n जहां एन हस्ताक्षरित प्रकार का प्रतिनिधित्व करने के लिए उपयोग की जाने वाली बिट्स की संख्या है)। [नोट: दो के पूरक प्रतिनिधित्व में, यह रूपांतरण वैचारिक है और बिट पैटर्न में कोई बदलाव नहीं है (यदि कोई छंटनी नहीं है)। - अंत नोट]

यह मूल रूप से कहता है कि जब हस्ताक्षरित हस्ताक्षर किए गए हस्ताक्षर से जाने का विशिष्ट रूपांतरण करते हैं, तो कोई भी हस्ताक्षरित-शैली रैपरराउंड मान सकता है। ,

एक अहस्ताक्षरित मात्रा के नकारात्मक n 2^से अपने मूल्य को घटाकर की गणना की जाती है:

अहस्ताक्षरित पूर्णांक का निषेध अच्छी तरह से 5.3.1 [expr.unary.op]/8 परिभाषित किया गया है जहां एन प्रमोटेड ऑपरेंड में बिट्स की संख्या है।

ये दो आवश्यकताएं प्रभावी रूप से 2 एस पूरक मशीन की तरह काम करने के लिए कार्यान्वयन को मजबूर करती हैं, भले ही अंतर्निहित मशीन 1 एस पूरक या हस्ताक्षरित परिमाण मशीन है।

+1

अच्छा जवाब, यद्यपि अपने खुद के प्रश्न के बावजूद, लेकिन +1। – Bathsheba

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