2013-07-23 7 views
6

को ब्रांच किए बिना किसी दिए गए बिट को सेट या रीसेट करें, उन्होंने मुझसे पूछा, आप थोड़ा सेट कैसे सेट या रीसेट करते हैं? यह एक बहुत ही सरल सवाल है और मैंने इसका उत्तर दिया।एक साक्षात्कार में

उसके बाद उन्होंने मुझसे पूछा, without branching करें। मुझे नहीं पता कि शाखा क्या है। मैं इसके लिए खोज करता हूं और मैं यहां आया था http://graphics.stanford.edu/~seander/bithacks.html

लेकिन अभी भी शाखाकरण और गैर-शाखाओं की अवधारणा नहीं मिल रही है। कृपया Branching समझाएं।

+4

मेरे जवाबी सवाल होगा होगा: कैसे नरक आप सेट या शाखाओं के साथ एक सा रीसेट करते हैं? – Art

+0

"सेट या रीसेट" करके उनका टॉगल मतलब है? आप इसे xor के साथ कर सकते हैं। –

+0

@Art ... मुझे ब्रांचिंग के बारे में कुछ नहीं पता ... बस मैं थोड़ा हेरफेर कर सकता हूं और थोड़ा सेट कर सकता हूं या रीसेट कर सकता हूं ... मैं जानना चाहता हूं कि शाखा क्या है? – someone

उत्तर

10

ब्रांचिंग का अर्थ है कि सीपीयू निष्पादन के निर्देशों में सशर्त कूद शामिल है। एक या तो विकल्प। जिसका अर्थ if, for -loop, while -loop, switch, ?: या कुछ ऐसा है जो बूलियन के आधार पर निर्णय लेता है।

लोग जो अक्सर भूल जाते हैं, उनमें से एक वर्ग शू-सर्किटिंग बुलियन ऑपरेटर और संभवतः (लेकिन सभी CPUs पर जरूरी नहीं) चीजें हैं जो सत्य मूल्यों का मूल्यांकन करती हैं, इसलिए int foo; ...; foo = !foo; कुछ CPUs पर एक शाखा होगी, लेकिन सभी नहीं (x86 पर नहीं)।

तो थोड़ा स्थापित करने के लिए:

i |= (1 << bit); 

थोड़ा रीसेट:

i &= ~(1 << bit); 

टॉगल एक सा:

i ^= (1 << bit); 

कोई शाखाओं। मैं वास्तव में यह नहीं देखता कि शाखा का उपयोग करने के लिए इसे इतना जटिल कैसे बनाया जाए।

कोई कारण शाखाओं के बारे में चिंता करना क्यों चाह सकता है शाखा भविष्यवाणी है। See this question and answer for an excellent explanation of why it matters.

+0

टॉगल: 'i^= (1 << बिट);' –

+0

@Art ... क्या यह x86 प्रोग्रामिंग से संबंधित है? क्षमा करें अगर मेरा प्रश्न गलत है। – someone

+0

नहीं, यह सामान्य प्रोग्रामिंग है। सभी (जब तक कि आप कुछ वास्तव में गूढ़ सामान नहीं जाते) सीपीयू के पास शाखा निर्देश होते हैं और शाखाओं की अवधारणा उन सभी में समान या कम होती है। – Art

5

हो सकता है वे तुम्हें एक सामान्य सेट लिखने के लिए कैसे/शाखाओं के बिना टुकड़ा रीसेट दिखाने के लिए चाहता था ...

यह

value = (value & ~(1 << bit)) | (bitval << bit); 

जहां bit बिट स्थिति है और bitval साथ पूरा किया जा सकता सेट के लिए 1 और रीसेट के लिए 0 है।

कुछ भी थोड़ा अधिक सामान्य है निम्नलिखित:

value = (value & ~(k1 << bit))^(k2 << bit); 

कि कई आपरेशनों लागू करता है:

  • k1=0 और k2=0
  • k1=0 और k2=1 कुछ नहीं करता है टॉगल सा
  • k1=1 और k2=0 बिट को साफ करता है
  • k1=1 और k2=1 बिट

अधिक आम तौर पर

value = (value & a)^x; 

साथ आप

  • aj=0 द्वारा एक ही समय में value के कई टुकड़े को बदलने का फैसला कर सकते हैं सेट, xj=0 → उन्हें 0
  • पर सेट करना 10
  • aj=0, xj=1 उन्हें इससे अछूते ही रहे
  • aj=1, xj=1 → उन्हें

flipping precomputed स्थिरांक a और x (aj और xj पर निर्भर करता है → 1

  • aj=1, xj=0 करने के लिए उन्हें स्थापित करने → मान रहे हैं स्थिरांक में जे-वें बिट के)।

    उदाहरण

    value = (value & 0x0F)^0x3C; 
    

    एक भी आपरेशन के साथ के लिए

    - leave untouched bit 0 and 1 
    - flip bits 2 and 3 
    - set to 1 bits 4 and 5 
    - set to 0 all other bits 
    
  • संबंधित मुद्दे