2015-03-26 9 views
8

monodevelop इस मोड़ से पता चलता है, तो:monodevelop मोड़ पता चलता है बिटवाइज़ संचालन में बयान

if (someBoolVar) 
    anotherBoolVar = true; 
इस में

:

anotherBoolVar |= someBoolVar; 

यह भी यह करता है जब मैं सेट anotherBoolVarfalse बजाय करने के लिए:

if (someBoolVar) 
    anotherBoolVar = false; 

बन जाता है:

anotherBoolVar &= !someBoolVar; 

कोई बता सकता है कि ये कथन कैसे बराबर हैं?

+1

मुझे पूरा यकीन है कि आखिरी व्यक्ति '& = ~ कुछ बुल्वर' होना चाहिए; 'आप '~' –

+14

खो रहे हैं आपका आईडीई चाहता है कि आप कम पठनीय कोड लिखें। इसकी सलाह को अनदेखा करें। –

+1

'|' (या), '&' (और) और '~' (नहीं) और बिटवाई ऑपरेटर हैं, इस मामले में इसे इन लाइन-लाइन असाइनमेंट में छोटा किया जा सकता है। आईडीई को अपने कोड को "सही" न होने दें यदि यह आपको भ्रमित करता है :) –

उत्तर

12

ठीक है, कार्यात्मक रूप से वे बराबर हैं।

पहला मामला आप true अगर someBoolVar को anotherBoolVar सेट करना चाहते हैं में true, क्या मूल्य anotherBoolVar वर्तमान में है, प्रतिस्थापन अभिव्यक्ति करता है कि की परवाह किए बिना है।

यह इस के लिए कम है:

anotherBoolVar = anotherBoolVar | someBoolVar; 

दूसरा प्रतिस्थापन भी कोड यह बदल देता है के रूप में ही होता है, और इस के लिए कम है:

anotherBoolVar = anotherBoolVar & (!someBoolVar); 

समाधान में छिपा हुआ है " bitwise "इस मामले में बूलियन चर की प्रकृति। और एक उल्टा मूल्य (~someBoolVar में परिवर्तित करता है) प्रभावी ढंग से कहेंगे "!someBoolVar में सेट की गई सभी बिट्स रखें और बाकी को साफ़ करें", जिसका अर्थ है कि someBoolVar सत्य है, तो यह गलत हो जाएगा, और आप ' anotherBoolVar प्रभावी ढंग से साफ़ कर देंगे।


अब, आप इस करना चाहिए?

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

+1

आपको ऐसा करने पर जोर देना चाहिए। नहीं। अन्य रोबोटों की तरह, आईडीई के पास कोड के साथ कोई भावनात्मक संबंध नहीं है और यह आईडीई स्पष्ट रूप से इसके मानवीय उपयोगकर्ताओं के बारे में परवाह नहीं करता है। :) – kingdango

+2

ऐसा लगता है कि मोनो डेवेल एक _dumb_ कंपाइलर की धारणा पर काम कर रहा है। कोई भी _decent_ कंपाइलर "तुलना-और-कूद" से बचने के लिए 'OR' या' AND' निर्देश में 'if' कथन' को '(ओ0' पर) अनुकूलित करेगा। ऊपर की तरफ, [मोनो डेवलप ओपन सोर्स] (https://github.com/mono/monodevelop) है, इसलिए यदि आपके पास गिटहब खाता है, तो आप एक बग (मुद्दा) अनुरोध दर्ज कर सकते हैं (@ LasseV.Karlsen आपको इसका जिक्र करना चाहिए आपके अंतिम पैराग्राफ में) –

+2

@kingdango [Obligatory xkcd] (https://www.xkcd.com/810)? –

2

उदा।

if (someBoolVar) 
    anotherBoolVar = true; 

तो जब someBoolVar है true यह

anotherBoolVar = (whatever boolean value of anotherBoolVar) | true; 

जो हमेशा सच करने के लिए मूल्यांकन करेंगे करने के लिए नीचे आता है।

0
if (someBoolVar) 
    anotherBoolVar = true; 

जो

if (someBoolVar) 
    anotherBoolVar = anotherBoolVar | someBoolVar; 
else 
    anotherBoolVar = anotherBoolVar | someBoolVar //Nop 

क्योंकि एक्स के बराबर है

if (someBoolVar) 
    anotherBoolVar = true; 
else 
    anotherBoolVar = anotherBoolVar //Nop 

के बराबर है | सच == सत्य और एक्स | झूठी == एक्स

और मैं तुम्हें पता है कि

anotherBoolVar |= someBoolVar 

anotherBoolVar = anotherBoolVar | someBoolVar 
2

पहला परिवर्तन के लिए के बराबर है मान लेते हैं, if निर्माण का अर्थ है:

someBoolVar is true ==> anotherBoolVar becomes true 
someBoolVar is false ==> anotherBoolVar is unchanged 

|= निर्माण का मतलब है:

someBoolVar is true ==> anotherBoolVar becomes (true | initial value) which is always true 
someBoolVar is false ==> anotherBoolVar becomes (false | initial value) which is always equal to the initial value 

इसी तरह की टिप्पणियां दूसरे परिवर्तन पर लागू होती हैं, हालांकि @Lasse V. Karlsen ने उल्लेख किया है, &= निर्माण में एक टिल्डे गुम हो रहा है।

+0

_ "... एक tilde गायब प्रतीत होता है" _ FYI, इसे "कम से कम मेरे द्वारा" एक "_bitwise NOT_ ऑपरेटर" कहा जाता है। अन्य इसे थोड़ा अलग कह सकते हैं। –

+0

ओह आओ। एक tilde और bitwise नहीं ऑपरेटर के बीच एक अंतर है, जैसे एक सारांश प्रतीक और यूनानी पत्र सिग्मा के बीच एक अंतर है। आप अर्थपूर्ण नाम के बजाय टाइपोग्राफ़िकल नाम का उपयोग करने के लिए मुझे गलत नहीं कह सकते हैं। –

+0

यदि आप मेरी टिप्पणी दोबारा पढ़ते हैं, तो मैं आपको गलत कहता हूं _didn't_। मैं बस इतना कह रहा था कि "bitwise not ऑपरेटर" भाषा अज्ञेयवादी है, लेकिन "tilde" सी आधारित भाषाओं के लिए विशिष्ट है। –

3

आईडीई कोड सिफारिशें अक्सर एक डबल एज तलवार होती हैं। हां, बयान terser हैं लेकिन वे भी संभावित रूप से भ्रमित कर रहे हैं (इसलिए आप सोच रहे हैं)। यदि someBoolVar गलत है

if (someBoolVar) 
    anotherBoolVar = someBoolVar; 

anotherBoolVar |= someBoolVar; 

क्योंकि |= शॉर्ट circuts के समान है। अगर कुछ बुलवार सत्य है तो यह शॉर्ट-सर्कट नहीं करता है और इसलिए कुछ बुल्वर मूल्य (सत्य) को दूसरे बुल्वर को असाइन करता है।

हालांकि अधिक terse कथन थोड़ा अनुकूलित किया जा सकता है, मैं आपको अपने कथन के साथ चिपकने की सलाह देता हूं क्योंकि यह अधिक अभिव्यक्तिपूर्ण और पठनीय है।

बयान मैं उन्हें एक पंक्ति में रखने की कोशिश करता है, तो के इन प्रकार के लिए:

if (someBoolVar) anotherBoolVar = someBoolVar;

+1

+1 लेकिन आपको [रॉस प्रेसनर ने किया था] (http://stackoverflow.com/a/29279979/1350209) के समान बूलियन तर्क तालिका जोड़नी चाहिए। यह समझाने में मदद करेगा कि वे बराबर क्यों हैं। सिर्फ यह कहकर कि वे समकक्ष हैं (अब या भविष्य में) जो बूलियन तर्क को समझ में नहीं आता है (गणित वर्ग के समान जो केवल 'पाप (x)^2 + cos (x)^2 = _why_ समझाए बिना 1'। –

1

शायद बूलियन बीजगणित पर Wikipedia article मदद करता है।

सुझाव एक सूक्ष्म अनुकूलन है जो जल्दबाजी में मैक्रो को बदल सकता है। जस्ट-इन-टाइम कंपाइलर if() कथन के लिए एक सशर्त शाखा उत्पन्न करता है, कम से कम माइक्रोसॉफ्ट द्वारा बनाए गए लोग कोड को अनुकूलित करने के लिए पर्याप्त स्मार्ट नहीं हैं। यदि आपको उत्पन्न मशीन कोड को देखकर मोनो जिटर बेहतर काम कर सकता है तो आपको देखना होगा।

  if (someBoolVar) anotherBoolVar = true; 
00007FFD989F3BB1 movzx  eax,cl 
00007FFD989F3BB4 test  eax,eax 
00007FFD989F3BB6 je   00007FFD989F3BBA // <=== here 
00007FFD989F3BB8 mov   dl,1 
00007FFD989F3BBA etc... 

ऊपर मशीन कोड में जेई निर्देश के समान सशर्त शाखाओं एक आधुनिक प्रोसेसर लिए परेशानी हैं, यह पाइपलाइन पर काफी निर्भर करता कोड शीघ्रता से संसाधन बनाने के लिए: विशिष्ट कोड पीढ़ी की तरह दिखता है। निर्देश डिकोडिंग और माइक्रो-ऑप्स पीढ़ी समय से पहले की जाती है। प्रीफ़ेचर के साथ भी वास्तव में एक बड़ा सौदा, यह अनुमान लगाने का प्रयास करता है कि कैश में कौन से मेमोरी स्थानों को उपलब्ध होना आवश्यक है ताकि मेमोरी सामग्री की आवश्यकता होने पर निष्पादन इंजन बंद न हो।प्रोसेसर के निष्पादन इंजन की कच्ची निष्पादन गति की तुलना में मेमोरी बहुत धीमी है।

एक प्रोसेसर में शाखा भविष्यवाणी है, यह ट्रैक करता है कि कोड को पहले निष्पादित किए जाने पर लिया गया था या नहीं। और मानता है कि शाखा फिर से वैसे ही व्यवहार करेगी। अगर यह गलत लगता है तो पाइपलाइन को फ्लश करने की जरूरत है। बहुत सारे काम फेंक दिए जाते हैं और जब प्रोसेसर बैक हो जाता है तो प्रोसेसर रुक जाएगा। अतिरिक्त लंबे स्टालों तब हो सकते हैं जब प्रीफेचर ने गलत अनुमान लगाया है, जो उसने किया है। एक good SO post है जो गलत भविष्यवाणी के परिणामों को बताता है।

बूलियन बीजगणित का उपयोग शाखा से बचाता है, यह एक OR या AND निर्देश उत्पन्न करेगा, वे एक चक्र लेते हैं और कभी भी पाइपलाइन को फ्लश नहीं कर सकते हैं। निश्चित रूप से एक माइक्रो-ऑप्टिमाइज़ेशन, यह केवल मैक्रो बदलता है जब यह कोड आपके कोड की ~ 10% के अंदर स्थित होता है जो आपके प्रोग्राम की गति निर्धारित करता है। आईडीई आपको यह बताने के लिए पर्याप्त स्मार्ट नहीं होगा कि यह मामला है, केवल एक प्रोफाइलर आपको दिखा सकता है।

Fwiw, ऐसे माइक्रो-ऑप्टिमाइज़ेशन हैं, प्रोग्रामर & & और || ऑपरेटरों को अनुपयुक्त। उन ऑपरेटरों के संक्षिप्त सर्किटिंग व्यवहार को हमेशा मशीन कोड में एक शाखा की आवश्यकता होती है। उस व्यवहार की हमेशा आवश्यकता नहीं होती है, आमतौर पर यह नहीं है और & और | ऑपरेटर बहुत तेज़ कोड उत्पन्न कर सकता है। यदि बाएं तरफ ऑपरेंड की खराब भविष्यवाणी की जाती है तो यह कोड 500% धीमा कर सकता है।

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