2011-01-15 20 views
5

एक दृष्टिकोण की जांच करने, इस हो सकता है: (सा आपरेशन का उपयोग कर)नकारात्मक पूर्णांक की जांच का उपयोग कर बिट संचालन

int num_bits = sizeof(int) * 8; //assuming 8 bits per byte! 
int sign_bit = given_int & (1 << (num_bits-1)); //sign_bit is either 1 or 0 
if (sign_bit) 
{ 
    cout << "given integer is negative"<<endl; 
} 
else 
{ 
    cout << "given integer is positive"<<endl; 
} 

इस समाधान के साथ समस्या की संख्या है प्रति बाइट बिट्स 8 नहीं हो सकता है, यह प्रति बाइट 9,10, 11 भी 16 या 40 बिट्स हो सकता है। बाइट का मतलब 8 बिट्स का मतलब नहीं है! वैसे भी, इस समस्या को आसानी से लिखकर,

//CHAR_BIT is defined in limits.h 
int num_bits = sizeof(int) * CHAR_BIT; //no assumption. 

यह ठीक लगता है। लेकिन क्या यह वास्तव में है? क्या यह मानक अनुरूप है? क्या होगा यदि ऋणात्मक पूर्णांक 2 के पूरक के रूप में प्रदर्शित नहीं किया गया है? क्या होगा यदि यह एक बाइनरी संख्या प्रणाली में प्रतिनिधित्व है कि केवल नकारात्मक पूर्णांक को इसके सबसे महत्वपूर्ण बिट में 1 रखने की आवश्यकता है?

क्या हम ऐसे कोड लिख सकते हैं जो पोर्टेबल और मानक अनुरूप दोनों होंगे?


संबंधित विषय:
Size of Primitive data types
Why is a boolean 1 byte and not 1 bit of size?

+16

'given_int <0' के साथ क्या गलत है? –

+2

@ क्रिस: कुछ भी गलत नहीं है। बस मैं इसे "बिट ऑपरेशंस का उपयोग करके" करना चाहता था। – Nawaz

+2

@ नवाज - यदि आपको '<' ऑपरेटर से कुछ तेज़ लगता है तो मुझे दिलचस्पी होगी। मुझे लगता है कि अधिकांश कंपाइलर '<' ऑपरेटर को जो कुछ भी आप खोजते हैं, उसे लागू करेंगे। लेकिन चीयर्स। –

उत्तर

2

इसी अहस्ताक्षरित प्रकार के पूर्णांक कास्ट और फिर तुम क्या हस्ताक्षर किए प्रतिनिधित्व प्रयोग में है के बारे में चिंता करने की जरूरत नहीं है। एकमात्र शेष मुद्दा यह है कि पैडिंग बिट्स हो सकते हैं। बिट रैपिंग की तरह कुछ

#define IS_NEG(x) ((unsigned_type)x & (unsigned_type)-1-(unsigned_type)-1/2) 
+2

यदि आप अपने जानवरों में 'uintmax_t' का उपयोग करते हैं तो आपको मूल प्रकार के' x' के बारे में चिंता करने की आवश्यकता नहीं होगी। –

+0

@ क्रिस: काफी सच है। उम्मीद है कि अनुकूलक वास्तव में बहुत अधिक बिट्स तक विस्तार से बच जाएगा, लेकिन मुझे यकीन नहीं है ... –

+0

@R: इस समाधान की व्याख्या? यह पोर्टेबल और मानक अनुरूप क्यों होना चाहिए? – Nawaz

0

उपयोग परिपत्र पारी का उपयोग कर तो आप अपने अंगूठे के नीचे अंतिम बिट प्राप्त कर सकते हैं: यहाँ कोई सा स्थानांतरण के साथ एक समाधान और बिट्स में आकार मिलान बिट्स में चौड़ाई पर इस प्रकार कोई निर्भरता है बिट स्ट्रिंग की शुरुआत में, और फिर bool neg = n & 1; इसे या कुछ। यहाँ बिट रैपिंग के लिए कुछ कोड है:

template <typename T> 
inline T rotate_left(T val, unsigned char shift=1) 
{ 
    static const bits = sizeof(T) * CHAR_BIT; 
    return (val >> (bits-shift)) | (val << shift); 
} 

template <typename T> 
inline T rotate_right(T val, unsigned char shift=1) 
{ 
    static const bits = sizeof(T) * CHAR_BIT; 
    return (val << (bits-shift)) | (val >> shift); 
} 

// And now for some platform-dependant specializations... 

#include <intrin.h> 

template<> 
inline unsigned char rotate_left(unsigned char val, unsigned char shift=1) 
{ 
    return _rotl8(val, shift); 
} 

template<> 
inline unsigned char rotate_right(unsigned char val, unsigned char shift=1) 
{ 
    return _rotr8(val, shift); 
} 

template<> 
inline unsigned int rotate_left(unsigned int val, unsigned char shift=1) 
{ 
    return _rotl(val, shift); 
} 

template<> 
inline unsigned int rotate_right(unsigned int val, unsigned char shift=1) 
{ 
    return _rotr(val, shift); 
} 

template<> 
inline unsigned long long rotate_left(unsigned long long val, unsigned char shift=1) 
{ 
    return _rotl64(val, shift); 
} 

template<> 
inline unsigned long long rotate_right(unsigned long long val, unsigned char shift=1) 
{ 
    return _rotr64(val, shift); 
} 
+0

मुझे आपके उत्तर में कोई चर्चा नहीं दिखाई देती है। क्या यह मानक अनुरूप और पोर्टेबल है? – Nawaz

+0

ऐसा लगता है जैसे यह होगा। मुझे इसके बारे में कोई समस्या नहीं दिख रही है। –

+0

नकारात्मक पूर्णांक का पता लगाने के लिए कैसे? – Nawaz

4

नोट: C और C++ अलग-अलग भाषाओं में हैं। उनके संबंधित मानकों को कुछ हद तक स्वतंत्र रूप से विकसित किया गया है और उनके पास संख्यात्मक प्रतिनिधित्व पर अलग-अलग औपचारिक प्रतिबंध हैं।


हम इस तरह के कोड है कि दोनों पोर्टेबल और मानक अनुरूप होना होगा लिख ​​सकते हैं?

यह मानते हुए कि आप की पहचान करने और एक संकेत है बिट की व्याख्या की एक सामान्य विधि की आवश्यकता होती है, मुझे लगता है कि आपके सवाल का जवाब नहीं।

सी ++ के बारे में है: मुझे नहीं लगता कि मानक एक स्पष्ट आवश्यकता है कि है एक संकेत बिट के अस्तित्व के लिए। यहां तक ​​कि यदि प्रत्येक कार्यान्वयन एक साइन बिट का उपयोग करता है, तो इस बात की कोई गारंटी नहीं है कि यह आपके कोड के अनुसार पहला (उच्च-आदेश) बिट है। इसके अलावा, बिट को आप जो मान रहे हैं उससे विपरीत व्याख्या हो सकती है (साइन बिट के लिए "1" मान का मतलब यह हो सकता है कि संख्या सकारात्मक है)।

सी 99 के संबंध में: भाषा को साइन बिट की आवश्यकता होती है और यह आवश्यक है कि साइन = 1 ऋणात्मक संख्या इंगित करता है (हालांकि यह "ऋणात्मक शून्य" हो सकता है)। हालांकि, भाषा मानक आपको यह निर्धारित करने का एक सामान्य तरीका नहीं देता है कि साइन बिट कहां है।

निम्न कोड सामान्य रूप से "साइन_मास्क" बनाने का प्रयास करता है, लेकिन यह पूरी तरह से सी 99 या सी ++ में काम करने की गारंटी नहीं देता है। विफलता के लिए कारण उन ऊपर उल्लेख किया है, लेकिन सबसे दिलचस्प है, यह एक "जाल प्रतिनिधित्व" (जैसे एक समता बिट त्रुटि के रूप में) आह्वान सकता शामिल हैं ...

#ifdef __cplusplus 
    #define INT_MAX std::numeric_limits<int>::max() 
    #define UINT_MAX std::numeric_limits<unsigned int>::max() 
#endif 

// assumes sign bit becomes high-order bit of unsigned 
    int sign_mask = INT_MAX^UINT_MAX; 

// fallback in case unsigned type doesn't take advantage of the sign-bit 
// This might invoke a "trap representation" on some platforms 
    if (sign_mask==0) sign_mask = ~INT_MAX; 

यह विकिपीडिया लेख कुछ अलग अलग तरीकों पर हस्ताक्षर किए संख्या हो सकता है पर चर्चा बाइनरी में प्रतिनिधित्व: Signed number representations

Here's an informative post about signed numbers in the C99 standard। R.s पद्धति पर

+0

@nober: आप कैसे कह सकते हैं '~ std :: numeric_limits :: अधिकतम(); 'वापसी * ​​साइन मास्क * चाहिए? – Nawaz

+0

परिणाम में सभी बिट्स सेट होंगे जिनका उपयोग किसी हस्ताक्षरित नंबर का प्रतिनिधित्व करने के लिए नहीं किया जाता है - दूसरे शब्दों में, केवल साइन बिट सेट किया जाएगा। यह मानता है कि अधिकतम मूल्य 2 की शक्ति से कम है, जो आम तौर पर मामला है, लेकिन संभवतः यह मानक द्वारा गारंटीकृत नहीं है। – nobar

+0

मेरा मुद्दा यह है कि यह बाइट के आकार के बारे में आपकी समस्या का समाधान करना चाहिए - लेकिन यह मैंने उल्लेख की गई किसी भी अन्य काल्पनिक चिंताओं को हल नहीं किया है। – nobar

0

विस्तार करना:

template <typename T> is_negative(T v) { 
    boost::make_unsigned<T>::type u(v); 
    return (u & (1 << std::numeric_limits<T>::digits - 1)); 
} 

आप, को बढ़ावा देने के उपयोग (make_unsigned type_traits में है) पसंद नहीं है सिर्फ अपने मंच के सबसे बड़े अहस्ताक्षरित int प्रकार का उपयोग करें।

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