बूलियंस पर बिटवाइज़ ऑपरेशन कैसे काम करता है?


26

मैं एडैबिट पर इस चुनौती पर आया था और इस बिटवाइज़ ऑपरेशन समाधान का काम नहीं कर सका।

notNotNot = (a,b) => !!(a%2 >> b)

चुनौती:

//Something which is not true is false, but something which is not not true is true! 
//Create a function where given n number of "not", evaluate whether it's true or false.

//Examples:
notNotNot(1, true) ➞ false
// Not true

notNotNot(2, false) ➞ false
// Not not false

notNotNot(6, true) ➞ true
// Not not not not not not true

मैंने उस शोधकर्ता को कुछ शोध किया:

बाईं ओर से सबसे छोटी बिट की प्रतियों को धक्का देकर दाएं मुड़ें, और दाएं बिट्स को गिरने दें।

मुझे लगता है कि मैं समझ गया (जैसे 5 >> 1कि 0101 >> 1जो मूल्यांकन करता है उसी के लिए 0010), लेकिन मैं यह नहीं देख सकता कि यह बूलियन के साथ कैसे काम करता है? मैं जानता हूँ कि trueकरने के लिए मूल्यांकन करता है 1और falseकरने के लिए 0।


3
एक बूलियन बस एक नंबर में तब्दील होने वाली है और फिर शिफ्ट होगी, इसलिए true= 1(दशमलव) = 01(बाइनरी) एक के द्वारा छोड़ी गई 10बाइनरी या 2दशमलव का उत्पादन करेगी ।
— वीएलजी

दरअसल, यह समाधान गलत है। उपरोक्त मामलों में यह काम करेगा, लेकिन विचार करें notNotNot(2, true): यह वापस आ जाएगा false, लेकिन सच नहीं ( !!true) होना चाहिए true...
— FZs

@FZs जो सही है। फ़ंक्शन केवल falseहल करने के लिए नोटों की एक विषम संख्या पर विचार करेगा true।
— वीएलएज

2
मैं notNotNot = (a,b) => !!((a%2)^b)इसके बजाय कहूंगा ...
— FZs

सिर्फ क्यों नहीं (a, b) => !!((a + b) % 2)?
— जोनास विलम्स

जवाबों:


16

आपके द्वारा दिए गए कार्य चुनौती को पूरा नहीं करते हैं। राइट शिफ्टिंग वो नहीं करेगा जो मांगा जाता है। उदाहरण के लिए, आपका notNotNot(6,true)है false, trueजब आपके फ़ंक्शन के माध्यम से नहीं डाला गया है।

आपका प्रश्न हालांकि बूलियन पर बिटवाइज़ ऑपरेशन के बारे में है। चूंकि ऑपरेटर पूर्णांक पर काम करते हैं >>और पसंद <<करते हैं, इसलिए जावास्क्रिप्ट पहले बूलियन मान को पूर्णांक में परिवर्तित करता है। तो true1 हो जाता है और false0. हो जाता है। यह देखने के लिए आप शून्य से शिफ्ट कर सकते हैं:

console.log("true is",true >> 0)
console.log("false is", false >> 0)
तो बूलियन्स पर बिटवाइज़ ऑपरेशन वास्तव में 0 या 1 पर केवल बिटवाइज़ ऑपरेशन है।

का उपयोग करते हुए !!एक आसान तरीका एक बूलियन में कुछ भी परिवर्तित करने के लिए है। यह कुछ भी लेता है जिसे झूठ के बराबर माना जाएगा (जैसे 0 null, undefinedया "") और वापस देता है false। इसी तरह कुछ भी जो सत्य है (जैसे 14, "हैलो", [4], {a: 1}) और वापस दे दें true। !!काम करता है क्योंकि पहला विस्मयादिबोधक अभिव्यक्ति का 'नहीं' देता है जो हमेशा होता है trueया false, फिर दूसरा विस्मयादिबोधक चिह्न उस ( falseया true) के विपरीत देता है ।

चुनौती से पीछे हटते हुए, यह न-ऑपरेटर को 'बार' लागू करना चाहता है और 'बी' मूल्य की तुलना करना चाहता है। तो कुछ इस तरह काम करेगा:

function notNotNot(a, b) { return !!(a%2 - b); }
console.log("notNotNot(1, true)",notNotNot(1, true));
console.log("notNotNot(2, false)",notNotNot(2, false));
console.log("notNotNot(6, true)",notNotNot(6, true));


9
मुझे लगता है कि "चुनौती" वास्तव में आपको यह महसूस करना चाहती है कि आप इसे बिना लूप के आसानी से कर सकते हैं ...
— BlueRaja - Danny Pflughoeft

2
@ BlueRaja-DannyPflughoeft वास्तव में। लूप के बिना इसे करने का सबसे सरल तरीका है, if (a % 2 === 1) return !b else return bलेकिन जैसा कि अन्य उत्तरों में दिखाया गया है, ब्रांचिंग या लूप्स के बिना इसे करने के तरीके हैं।
— वीएलएजी

हां, लेकिन यह सवाल चुनौती देने के बारे में नहीं था - यह बिटवाइज़ ऑपरेटर और बूलियन मूल्यों के बारे में था। लेकिन मैंने अपना जवाब एक गैर-लूप और गैर-अगर तरीके से अपडेट किया है।
— हमेशा लर्निंग

14

बिटवाइज़ ऑपरेटर हमेशा अपने ऑपरेंड को पूर्णांक में परिवर्तित करते हैं। तो, 4 >> trueएक ही है 4 >> 1जो एक स्थिति से थोड़ा सा बदलाव करेगा

(decimal) 4 = (binary) 100

(binary) 100 >> 1 = (binary) 010

(binary) 010 = (decimal) 2

console.log(4 >> true);

तो, का उपयोग करना trueया उपयोग falseकरने के लिए एक गोल चक्कर रास्ता है 1या 0।

notNotNotसमारोह बहुत ही सरल ऑपरेशन के कुल मिलाकर,:

  1. a%2पहले नंबर को 0सम या 1विषम के लिए परिवर्तित करता है ।
  2. >> bके 0लिए falseया 1स्थिति के लिए या तो पदों से सही बदलाव true।
    • aविषम है (1) और bहै false=1
      • दाहिनी ओर शून्य शिफ्ट है, इसलिए संख्या समान रहती है।
    • aविषम है (1) और bहै true=0
      • एकमात्र सेट बिट 1को सही और स्थानांतरित कर दिया गया है।
    • aसम है (०) और bहै false=0
      • दाहिनी ओर शून्य शिफ्ट है, इसलिए संख्या समान रहती है।
    • aसम है (०) और bहै true=0
      • आधार संख्या वह है 0जिसमें कोई बिट सेट नहीं है, इसलिए किसी भी राशि को सही तरीके से स्थानांतरित करने से इसमें बदलाव नहीं होता है।
  3. !!() परिणाम को बूलियन में परिवर्तित करता है।

उस के साथ, यहाँ समाधान गलत है, क्योंकि notNotNot(2, true)उत्पादन होगा false- aसम है और bहै true। उम्मीद है कि यह उत्पादन करेगा है trueके बाद से !!true = true। वही समस्या किसी भी संख्या और के लिए मौजूद है true।

इसे राइट शिफ्ट के बजाय बिटवाइज़ एक्सओआर का उपयोग करके आसानी से तय किया जा सकता है:

  • aविषम है (1) और bहै false=1
    • दोनों मैच, इसलिए वे फ़्लिप कर रहे हैं 0
  • aविषम है (1) और bहै true=0
    • वे मेल नहीं खाते, इसलिए हम मिलते हैं 1
  • aसम है (०) और bहै false=0
    • दोनों मेल खाते हैं, इसलिए हम मिलते हैं 0
  • aसम है (०) और bहै true=1
    • वे मेल नहीं खाते, इसलिए हम मिलते हैं 1

notNotNot = (a,b) => !!(a%2 ^ b);

console.log("!!true = ", notNotNot(2, true))
console.log("!!!true =", notNotNot(3, true))
console.log("!!false = ", notNotNot(2, false))
console.log("!!!false = ", notNotNot(3, false))

//bonus
console.log("true = ", notNotNot(0, true))
console.log("false = ", notNotNot(0, false))

पूर्णता के लिए, यदि आप पूरी तरह से बिटवाइज़ ऑपरेशन चाहते हैं, तो:

मोडुलो ऑपरेशन %2को एक बिटवाइज़ में बदला जा सकता है और &1सबसे कम बिट प्राप्त किया जा सकता है । यहां तक ​​कि संख्याओं के लिए, यह तब से निकलेगा 0जब आप कंप्यूटिंग करेंगे

xxx0
&
0001

जो शून्य है। और विषम संख्याओं के लिए भी यही लागू होता है लेकिन आपको परिणाम के रूप में एक मिलेगा:

xxx1
&
0001

तो के परिणाम a&1और a%2समान हैं। इसके अलावा, भले ही बिटवाइज़ ऑपरेशन्स संख्या को 32-बिट हस्ताक्षरित पूर्णांक में परिवर्तित कर दें जो कि समता को संरक्षित नहीं करेगा।


4

सबसे पहले, (a,b) => !!(a%2 >> b)उदाहरण के परिणामों से मेल नहीं खाता। मैं इसका उपयोग कर रहा हूँ बिल्कुल टूट जाएगा notNotNot(6, true) ➞ true।

  • मुट्ठी a%2, बस aशेष 2 से विभाजित करें। तो हम एक सम संख्या के लिए 0 और विषम संख्या के लिए 1 प्राप्त करेंगे। a = 6 a%2 = 0इस मामले में।
  • फिर 0 >> bदाईं ओर से 1 नंबर को शिफ्ट करें क्योंकि जैसा कि आपने कहा था कि trueमूल्यांकन करता है 1। तो हम प्राप्त करते हैं 0 >> 1 = 0।
  • अंतिम !!(0), सरल है, और ऐसा ही तोड़ा जा सकता है !0 = true, तब !true = false।

इसलिए हम इस रूप में लंबे समय के रूप में के बारे में लगता है कि अगर bहै true, हम हमेशा वापस आ जाएगा false। चलो कहते हैं कि हम एक = 5, ख = सच करने के लिए मूल्यांकन करने के लिए है 5%2 = 1, 1 >> 1 = 0। आप मॉड ( %2) के कारण देख सकते हैं कि हमारे पास केवल 1 या 0 होगा (केवल कभी 1 अंक होगा) और यह सच है कि हमेशा 1 से दूर होगा जब हमारे पास होगा।

इस समस्या को देखने का एक सरल तरीका एक isEvenOrNotफ़ंक्शन की तरह है। तो aवह संख्या है जिसे हम जाँच रहे हैं और bयह जाँचने के लिए बूलियन है कि यह (सत्य) है या नहीं (झूठी) भी है। यह काम करता है क्योंकि हर दूसरा notजोड़ा सही होगा।

तो बिटवाइज़ का उपयोग करने वाला एक समाधान कुछ इस तरह हो सकता है (a,b) => !!(a&1 ^ b):। मैं आपको नीचे तोड़ने का मज़ा दूँगा कि यह क्यों काम करता है! :)

बूलियन के साथ शिफ्ट कैसे काम करता है, यह समझाने में थोड़ा और अधिक। तो trueजैसा कि आपने कहा कि 1 होगा और असत्य होगा। 0. जैसा आपके उदाहरण में दिखाया गया 0101 >> trueहै, वैसा ही है 0101 >> 1।

आशा है कि ये आपकी मदद करेगा।

मैंने बिटवाइज़ के लिए एक संदर्भ के रूप में निम्नलिखित का उपयोग किया: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators


1
(a%2)  //ignore all but the least significant bit (LSB)
(a%2 >> b )  //if TRUE,  shifts right, resolves to 0
               //if FALSE, no shift,     resolves to LSB

// 0 and LSB are both integers so convert to boolean by using logical/boolean NOT
!(a%2 >> b ) //resolves to the boolean which it is NOT
!!(a%2 >> b ) //resolves to the boolean which it is NOT NOT

एनबी या तो बूलियन के लिए, मूल बूलियन में भी संख्या का परिणाम होता है, विपरीत बूलियन में NOTs के विषम संख्या में परिणाम होता है

किसी भी संख्या का LSB निर्धारित करता है कि संख्या विषम है या सम। (0 सम, 1 विषम)


1

मैं देखता हूं कि आपका कार्य है:

/* Create a function where given n number of "not",
   evaluate whether it's true or false.*/

मुझे नहीं पता कि आप notnotnotमेरे लिए फ़ंक्शन क्यों लिख रहे हैं, यह वह नहीं है जो कार्य पूछता है।

इसलिए कार्य के अनुसार मैंने वह कार्य किया not जो कई "नोट" को स्वीकार करता है और उनका मूल्यांकन करता है।

पहला तरीका

function not(n) {
  return Boolean(n - n - 1);
}

XOr (^) का उपयोग करने का दूसरा तरीका

function not(n) {
  return Boolean(bool ^ (bool - 1));
}

@VLAZ द्वारा इंगित मॉड (%) का उपयोग करने का तीसरा तरीका

function not(n) {
  return Boolean(n % 2);
}

चौथा रास्ता बिटवाइज़ और () का उपयोग करते हुए

function not(n) {
  return Boolean(n & 1);
}

परीक्षा

not(0)
//> false 
not(1)
//> true
not(2)
//> false
not(515)
//> true

1
बिट हेरफेर यहां उपयोगी है, क्योंकि हम राशि के बारे में परवाह नहीं करते हैं n- केवल यह कि क्या यह भी अजीब है या नहीं, क्योंकि किसी भी दो नोटों को रद्द नहीं किया गया है, इसलिए !!!!!bयह उसी तरह है !b। इसलिए हमें एक लूप की आवश्यकता नहीं है अगर हम बस लेते हैं n%2- हम 1नहीं करेंगे और 0"इसे वही रखें" के लिए। चूंकि हमारे पास एक संख्या है, हम बस बिटवाइज़ ऑपरेशन कर सकते हैं।
— वीएलएज़

वैसे मैंने इस बारे में नहीं सोचा था लेकिन आप सही कह रहे हैं कि हम केवल 0 और 1 के साथ काम कर रहे हैं, धन्यवाद, यह एक उपयोगी टिप्पणी है :)
— SaymoinSam

0

पहले विश्लेषण समाधान देता है

notNotNot(oddNumber, true)  ➞ false
notNotNot(evenNumber, true) ➞ true

notNotNot(oddNumber, false)  ➞ true
notNotNot(evenNumber, false) ➞ false

अब विश्लेषण के लिए (a,b) => !!(a%2 >> b)

a%2 == 0 ➞ even number
a%2 == 1 ➞ odd number

// For a%2 == 0

a%2 >> b ➞ if b is true  ➞ 0 >> 1 ➞ 0   // Not working
a%2 >> b ➞ if b is false ➞ 0 >> 0 ➞ 0


// For a%2 == 1

a%2 >> b ➞ if b is true  ➞ 1 >> 1 ➞ 0
a%2 >> b ➞ if b is false ➞ 1 >> 0 ➞ 1

Thats का मतलब है कि यह काम नहीं कर रहा notNotNot(6, true)है, trueलेकिन वर्तमान समाधान देता है false।

हम ^इसे सही करने के लिए (XOR) ऑपरेटर की तरह कर सकते हैं(a,b) => !!(a%2 ^ b)

अब विश्लेषण के लिए (a,b) => !!(a%2 ^ b)

a%2 == 0 ➞ even number
a%2 == 1 ➞ odd number

// For a%2 == 0

a%2 ^ b ➞ if b is true  ➞ 0 ^ 1 ➞ 1   // Now working
a%2 ^ b ➞ if b is false ➞ 0 ^ 0 ➞ 0


// For a%2 == 1

a%2 ^ b ➞ if b is true  ➞ 1 ^ 1 ➞ 0
a%2 ^ b ➞ if b is false ➞ 1 ^ 0 ➞ 1

!(a%2 ^ b) use `!` to make int as boolean but solution result will reversed then
!!(a%2 ^ b) use `!` again to reversed it again and make it correct.

उदाहरण:

notNotNot = (a,b) => !!(a%2 ^ b);

console.log("!!!!true = ", notNotNot(4, true))
console.log("!!!!false = ", notNotNot(4, false))
console.log("!!!true =", notNotNot(3, true))
console.log("!!!false = ", notNotNot(3, false))

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.