2009-11-03 6 views
10

दूसरे दिन, I came across इस संरचना: कुछ उदाहरण सी ++ कोड मेंकैसे पोर्टेबल एक हस्ताक्षरित प्रकार के लिए -1 कास्टिंग कर रहा है?

static_cast<size_type>(-1) 

है, जो (जहां size_type से है के विवरण के आधार पर) निम्नलिखित सी के बराबर होने की संभावना है:

(size_t)(-1) 

जैसा कि मैं इसे समझता हूं, यह इस तथ्य के आधार पर काम करता है कि दो में से 1 का प्रतिनिधित्व अंकगणितीय 11111...1 है, जो आपके पास जितने बिट्स हैं, इसलिए यह अधिकतम मूल्य प्राप्त करने का एक त्वरित तरीका है जैसे एक हस्ताक्षरित प्रकार size_t पकड़ सकता है। हालांकि, मेरी समझ यह भी है कि सी गारंटी नहीं देता है कि जुड़वां पूरक का उपयोग किया जाएगा; यदि सी कार्यान्वयन किसी के पूरक का उपयोग करता है, तो यह अधिकतम मूल्य से 1 कम होगा, और यदि यह हस्ताक्षरित परिमाण का उपयोग कर रहा है, तो यह अधिकतम मूल्य से अधिक आधा होगा।

क्या कोई झुर्रियां है जो मुझे याद आ रही है कि यह बीमा करता है कि यह हस्ताक्षरित पूर्णांक के प्रतिनिधित्व के बावजूद सही काम करता है? क्या यह सी और सी ++ के बीच भिन्न है (कई आश्चर्यजनक चीजें करते हैं)?

+3

यदि आप सुनिश्चित करना चाहते हैं, तो हमेशा 'std :: numeric_limits :: अधिकतम()' है। – UncleBens

+0

मुझे लगता है कि इस तरह की स्थितियां हैं कि आपके पास static_cast और भाषा में reinterpret_cast है - static_cast आपको कुछ अनुमानित (और इस प्रकार उपयोगी) दे सकता है, लेकिन कुछ प्लेटफ़ॉर्म पर धीमे कार्यान्वयन हो सकते हैं, जबकि reinterpret_cast किसी भी गारंटी के साथ दूर हो सकता है। – Kylotan

+3

यह आईएमएचओ सभी एक बिट्स प्राप्त करने का सबसे अच्छा तरीका है।'~ 0U' का उपयोग करने वाले विकल्प भी (और यदि आप 'यू' जोड़ना चाहते हैं और' 0 0 'करते हैं तो आप उदाहरण के लिए सभी बिट्स 0 के साथ समाप्त कर सकते हैं) - लेकिन' हस्ताक्षर 'प्रकार पर' -1' कास्ट का उपयोग करके , यह हमेशा प्रकार से स्वतंत्र काम करता है। तो आपको 'यूएलएल' का उपयोग करने या पहले 'हस्ताक्षरित शॉर्ट' पर कास्ट करने की परवाह नहीं है - आप केवल '-1' का उपयोग कर सकते हैं और इसे असाइन कर सकते हैं :) यह भी देखें http://stackoverflow.com/questions/809227/ यह-सुरक्षित-से-उपयोग-1-टू-सेट-ऑल-बिट्स-टू-सच्चा –

उत्तर

19

हस्ताक्षरित अंकगणितीय गारंटी पर आवश्यकताएं जो एक हस्ताक्षरित प्रकार के लिए -1 कास्टिंग करती हैं, लक्ष्य प्रकार के लिए सबसे बड़ी संख्या का उत्पादन करेगी। सी 99, §6.2.5/9: "... जिसके परिणामस्वरूप परिणामस्वरूप हस्ताक्षरित पूर्णांक प्रकार द्वारा प्रतिनिधित्व नहीं किया जा सकता है, वह मॉड्यूल को कम कर देता है जो कि सबसे बड़ा मान से अधिक होता है जिसे परिणामी प्रकार द्वारा दर्शाया जा सकता है।"

यह सी और सी ++ में समान है (सी ++ मानक में, समान शब्द फुटनोट 41 में पाया जाता है - यह मानक नहीं है, लेकिन यह अन्य शब्द समझा रहा है)।

+6

सी ++ के लिए, मानक शब्द '4.7/2 पर है ' –

+0

धन्यवाद! यह वास्तव में झुर्रियों के बारे में सोच रहा था। – Pillsy

14

एक "सुरक्षित" पक्ष पर हो सकता है और इसे "सही" (C++) जिस तरह से, एसटीएल को देख लायक करने के लिए:

std::numeric_limits<size_t>::max() 
+3

इसका एकमात्र नकारात्मक पक्ष यह है कि मान निरंतर अभिव्यक्ति नहीं है। आप 'integral_constant ', लेकिन 'integral_constant :: अधिकतम()>' काम नहीं करता है :( –

2

आप अधिकतम (या कम से कम) प्राप्त करने के लिए देख रहे हैं का मूल्य पोर्टेबल तरीके से एक निश्चित प्रकार, निम्नानुसार मानक numeric_limits कक्षा का उपयोग करना सबसे अच्छा है।

#include <limits> 

size_type max = std::numeric_limits<size_type>::max() 
size_type min = std::numeric_limits<size_type>::min() 

मुझे लगता है कि इन कार्यों में से कुछ कार्यान्वयन डाली आप मंच इष्टतम तरीका न्यूनतम/अधिकतम पर प्राप्त करने के लिए के रूप में वर्णन कर सकते हैं।

5

"जैसा कि मैं इसे समझता हूं, यह इस तथ्य के आधार पर काम करता है कि दो में से 1 का प्रतिनिधित्व अंकगणित पूरक है ..."।

नहीं, यह उस तथ्य पर आधारित नहीं है। यह मानक आवश्यकता पर आधारित है, कि एन-बिट हस्ताक्षरित प्रकार में परिवर्तित किए गए गायन मूल्यों को एक हस्ताक्षरित मान उत्पन्न करना होता है, जो मूल हस्ताक्षरित एक मॉड्यूलो 2^एन के "बराबर" है।

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

+0

उह ... निष्पक्ष होने के लिए: मानक को लिखा गया है कि यह सटीक रूप से सीपीयू पर सरल कार्यान्वयन के लिए अनुमति देता है जो 2 के पूरक अंकगणित करता है। यह निश्चित रूप से ** नहीं है गलत ** एक स्पष्टीकरण में 2 के पूरक का आह्वान करने के लिए। हार्डवेयर मानकों को हार्डवेयर और उपयोगकर्ता की जरूरतों को पूरा करने के लिए मौजूद है, दूसरी तरफ नहीं। –

+0

मैं "उपयोगकर्ता की ज़रूरतों को पूरा करने" के साथ सहमत हूं। लेकिन "सेवा हार्डवेयर की जरूरतें "? ... सं। – AnT

+0

मैंने पहले जवाब कम कर दिए हैं, जब मैं उन्हें पढ़ता हूं" मान 'UINT_MAX' है क्योंकि दो के पूरक '-1' में सब कुछ एक है।" बस इसे पीछे की तरफ था आर, मैं इस जवाब को ऊपर उठाऊंगा। –

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