2010-11-12 11 views
21

केवल बिटवाई ऑपरेटरों (|, &, ~, ^, >> < <) और अन्य बुनियादी ऑपरेटरों जैसे +, -, और! का उपयोग करके, "= = "नीचे?बिटवाई ऑपरेटरों के साथ "==" को बदलना

int equal(int x, int y) { 
    return x == y; 
} 
+1

यह समझने के लिए वास्तव में एक बिटवाइज़ स्तर पर कैसे कंप्यूटर "==" पर लग रहा है देखने के लिए "==" के साथ चल रहा है और इसी तरह के ऑपरेटरों एक ही फैशन में दोहराया जा सकता है, तो लगता है ज्यादातर है । –

+0

@ जेन्स: ["होमवर्क टैग ... अब निराश है,"] (http://meta.stackoverflow.com/q/10812) लेकिन, @ not_l33t, कृपया (हमेशा के रूप में) [सामान्य दिशानिर्देश] का पालन करें (http : //tinyurl.com/so-hints): किसी विशेष प्रतिबंध को बताएं, दिखाएं कि आपने अभी तक क्या प्रयास किया है, और इस बारे में पूछें कि विशेष रूप से आपको क्या भ्रमित कर रहा है। –

+0

जब आप किसी इंट की सीमा तक पहुंचते हैं तो आवश्यकताएं क्या होती हैं? अर्थात। INT_MAX, INT_MIN? या क्या इसे केवल एक छोटी सी सीमा के लिए काम करना है? –

उत्तर

18

दो नंबर के बराबर हैं, तो उन दोनों के बीच कोई अंतर नहीं है:

int equal(int x, int y){ 
    return !(x-y); 
} 
+0

मुझे यह दृष्टिकोण पसंद है। +1 –

+5

हालांकि वास्तव में थोड़ा सा ऑपरेटर का उपयोग नहीं कर रहा है। – Yada

+0

@Yada: लेकिन यह एक "बेसिक" ऑपरेटर का उपयोग करता है :) – AbdullahC

58

याद रखें कि एक XORNOT EQUALS के रूप में बिल्कुल वैसा ही है और XNOR बिल्कुल EQUALS के समान है। तो, निम्नलिखित आप दे देंगे आप क्या चाहते हैं:

return !(x^y); 
+1

आप लॉजिकल ऑपरेटरों के साथ बिट-वार जोड़ रहे हैं, जो भ्रमित हो सकता है। –

+0

नहीं यह बुरा है: पी –

+6

यह स्वीकार्य समाधान से बेहतर है, क्योंकि परिभाषा के अनुसार एक्सओआर एडीडी से तेज है (जोड़ने के लिए परिवहन लेना है, इसलिए यह बहुत स्केलेबल नहीं है)। – ruslik

2

यह उदाहरण घटाव के रूप में ही है, लेकिन अधिक स्पष्ट है कैसे कुछ आर्किटेक्चर रजिस्टर तुलना करते हैं (जैसे एआरएम, मुझे विश्वास है)।

return !(1 + ~x + y); 

1 एएलयू में कैर्री-बिट इनपुट को दर्शाता है। एक नंबर x बिटवाई पूरक है। पूरक लेना और जोड़ना 1 के दो पूरक का उत्पादन करता है (x-x बन जाता है), और फिर समानता निर्धारित करने के लिए अंतर प्राप्त करने के लिए इसे दूसरे नंबर में जोड़ा जाता है।

तो यदि दोनों संख्या बराबर हैं, तो आपको -x + x => 0 मिलते हैं।

(एक रजिस्टर स्तर पर ! ऑपरेटर नहीं किया गया है, और आप बस हालत कोड या झंडे रजिस्टर के "शून्य बिट" का परीक्षण करते हैं, जो सेट हो जाता है यदि रजिस्टर ऑपरेशन शून्य का परिणाम उत्पन्न करता है, और स्पष्ट है । अन्यथा)

-1

इस

int equal(int x, int y){ 
    if((x & ~y) == 0) 
     return 1; 
    else 
     return 0; 
} 

स्पष्टीकरण पर लेने के लिए मेरे: x == y, तो x & ~y0 वापसी 1, और वापसी 0 x!=y के रूप में करने के लिए मूल्यांकन करता है।

Edit1: The above is equivalent to 

int equal(int x, int y){ 
    return !(x & ~y) ; // returns 1 if equal , 0 otherwise. 
} 

ऊपर कोड कुछ मामलों में सबसे महत्वपूर्ण बिट 1. में बदल जाता है समाधान जोड़ने के लिए एक 1. यानी सही जवाब

return !(x & (~y +1)); 
+0

दो समस्याओं में प्रदर्शित नहीं किया जा सकता है, तो यह अनिर्धारित व्यवहार का आह्वान कर सकता है। 1) यह जांच करता है कि 'y' में' x' सेट के रूप में सभी समान बिट्स हैं, * नहीं * कि 'x == y'। 2) आप '== 'का उपयोग कर रहे हैं भले ही यह न तो चाहता था और न ही आवश्यक है। –

+2

3) बस 'if' का उपयोग करने के बजाय इसे वापस करें। – mpen

12

है सी ! ऑपरेटर वास्तव में सिर्फ आशुलिपि है है में विफल रहता है != 0 के लिए, इसलिए इसका उपयोग धोखाधड़ी के बहुत करीब लगता है :)

यहां मेरी बिट लेफ्ट ऑपरेशंस का उपयोग कर लिया गया है, जिसमें 32-बिट दो पूरक मशीन को अंकगणितीय दाएं बदलावों के साथ माना जाता है (तकनीकी रूप से, सी अंकगणितीय दाएं बदलावों में अपरिभाषित हैं, लेकिन हर सी संकलक मैंने कभी एक दो के पूरक मशीन पर देखा है सही ढंग से इस का समर्थन करता है):

int t = (x - y) | (y - x); // <0 iff x != y, 0 otherwise 
t >>= 31; // -1 iff x != y, 0 otherwise 
return 1 + t; // 0 iff x != y, 1 otherwise 

जिसके अनुसार, वास्तविक compilers इस समस्या नहीं है। असली हार्डवेयर वास्तव में तुलना के लिए सीधा समर्थन है। विवरण वास्तुकला पर निर्भर करते हैं, लेकिन वहाँ दो बुनियादी मॉडल है:

  1. स्थिति कोड अंकगणितीय आपरेशनों के लिए लौट आए (जैसे x86 और एआरएम ऐसा करने)। इस मामले में, आमतौर पर एक "तुलना" निर्देश होता है जो दो मानों को घटाता है, एक पूर्णांक रजिस्टर पर वापस नहीं लिखता है बल्कि परिणाम के आधार पर स्थिति कोड/झंडे सेट करता है।
  2. अधिक आरआईएससी-जैसे प्लेटफार्मों में आमतौर पर "शाखा अगर बराबर" होती है और परिणामस्वरूप कम से कम शाखा होती है जो परिणाम के आधार पर तुलना और शाखा करता है। यह मूल रूप से सी कोड

    if (a == b) goto label; 
    

    या

    if (a < b) goto label; 
    

    सभी में एक मशीन अनुदेश के बराबर है।

+0

उत्कृष्ट उदाहरण! लेकिन क्यों न सिर्फ "वापसी टी <0? झूठी: सच" का उपयोग न करें (अगर मान लें कि विधि बुलियन है)? –

+0

जैसा कि मैं इसे समझता हूं, ओपी शाखाकरण को छोड़ देता है – edgerunner

1

XOR के रूप में, (x^y) 0 वापस आ जाएगी केवल बराबर मूल्यों के लिए के रूप में (! =) एक ही है इसलिए। मेरा लेना निम्नलिखित है क्योंकि यह समझदार है, बिट-वार ऑपरेटर का उपयोग करता है और काम करता है।

int notEqual(int x, int y){ 
     return (x^y); 
} 
संबंधित मुद्दे