बिटवाइज़ पूरक ऑपरेटर (~ टिल्ड) कैसे काम करता है?


जवाबों:


279

याद रखें कि नकारात्मक संख्या को सकारात्मक समकक्ष के दो पूरक के रूप में संग्रहीत किया जाता है। एक उदाहरण के रूप में, यहाँ दो के पूरक में -2 का प्रतिनिधित्व है: (8 बिट)

1111 1110

जिस तरह से आप इसे प्राप्त करते हैं वह एक संख्या के द्विआधारी प्रतिनिधित्व को लेने से होता है, इसके पूरक लेता है (सभी बिट्स को सम्मिलित करता है) और एक को जोड़ता है। दो 0000 0010 के रूप में शुरू होता है, और बिट्स inverting द्वारा हम 1111 1101 प्राप्त करते हैं। एक को जोड़ने से हमें ऊपर परिणाम मिलता है। पहला बिट सांकेतिक बिट है, एक नकारात्मक को दर्शाता है।

तो आइए एक नज़र डालते हैं कि हम ~ 2 = -3 कैसे प्राप्त करते हैं:

यहाँ दो फिर से है:

0000 0010

बस सभी बिट फ्लिप और हम प्राप्त:

1111 1101

खैर, दो के पूरक में -3 ​​कैसा दिखता है? सकारात्मक 3 से शुरू करें: 0000 0011, सभी बिट्स को 1111 1100 पर फ्लिप करें, और एक को नकारात्मक मान (-3), 1111 1101 में जोड़ें।

तो अगर आप बस 2 में बिट्स को उल्टा करते हैं, तो आपको दो का पूरक प्रतिनिधित्व मिलता है -3।

पूरक ऑपरेटर (~) सिर्फ फ्लिप बिट्स। इन बिट्स की व्याख्या करना मशीन पर निर्भर है।


43
एक अन्य बात का उल्लेख शायद यह है कि फ्लिप को 1s पूरक कहा जाता है, 1. जोड़ने से पहले
क्रिस एस

3
यह उन लोगों की मदद कर सकता है जो वन के कॉम्प्लिमेंट और टू के कॉम्पटिशन से अवगत नहीं हैं। उनके बारे में यहां पढ़ें। en.wikipedia.org/wiki/Ones%27_complement en.wikipedia.org/wiki/Two%27s_complement
साईं

1
क्या वह बिटवाइज़ नहीं ऑपरेटर नहीं है?
ब्रैडन बेस्ट

3
मशीन कैसे जानती है कि उसे उच्च सकारात्मक संख्या के बजाय दो पूरक ऋणात्मक संख्या मिल रही है? क्या इसकी वजह यह है कि संबंधित भाषा का प्रकार सिस्टम यह दर्शाता है कि प्रकार एक हस्ताक्षरित इंट बनाम बनाम अहस्ताक्षरित है?
GL2014

@ GL2014 मुझे लगता है कि आपने अपने प्रश्न का उत्तर दिया है। मेरी समझ में, यह है कि मशीन को पहली जगह पर कैसे काम करने के लिए डिज़ाइन किया गया था।
geekidharsh

40

~ मूल्य में बिट्स flips।

क्यों ~2है -3कैसे संख्या बिटवाइज़ प्रतिनिधित्व कर रहे हैं के साथ क्या करना है। संख्याओं को दो के पूरक के रूप में दर्शाया गया है ।

तो, 2 द्विआधारी मूल्य है

00000010

और ~ 2 बिट्स फ़्लिप करता है इसलिए मूल्य अब है:

11111101

जो, -3 का बाइनरी प्रतिनिधित्व है।


2
11111101 == दशमलव 253 बनाम -3 नहीं है?
AKS

10
निर्भर करता है कि यह एक हस्ताक्षरित या अहस्ताक्षरित पूर्णांक का प्रतिनिधित्व करता है।
बजे

18

जैसा कि दूसरों ने उल्लेख किया है ~कि फ़्लिप बिट्स (एक से शून्य और एक से शून्य में बदल जाता है) और चूंकि दो के पूरक का उपयोग किया जाता है, इसलिए आपको वह परिणाम मिलता है जो आपने देखा था।

जोड़ने के लिए एक बात यह है कि दो के पूरक का उपयोग क्यों किया जाता है, यह इसलिए है कि नकारात्मक संख्याओं पर संचालन सकारात्मक संख्याओं के समान होगा। -3उस संख्या के बारे में सोचें जिसे 3शून्य प्राप्त करने के लिए जोड़ा जाना चाहिए और आप देखेंगे कि यह संख्या है 1101, यह याद रखें कि द्विआधारी जोड़ प्राथमिक स्कूल (दशमलव) की तरह है इसके अलावा आप केवल एक को ले जाते हैं जब आप 10 के बजाय दो हो जाते हैं ।

 1101 +
 0011 // 3
    =
10000
    =
 0000 // lose carry bit because integers have a constant number of bits.

इसलिए 1101है -3, बिट्स आप प्राप्त फ्लिप 0010जो दो है।


8

यह ऑपरेशन एक पूरक है, एक निषेध नहीं।

विचार करें कि ~ 0 = -1, और वहां से काम करें।

नकार के लिए एल्गोरिथ्म है, "पूरक, वेतन वृद्धि"।

क्या तुम्हें पता था? वहाँ भी "किसी के पूरक" जहां उलटा संख्या है कर रहे हैं सममित, और यह दोनों एक 0 और एक है -0।


6

मुझे पता है कि इस सवाल का जवाब बहुत पहले पोस्ट किया गया था, लेकिन मैं उसी के लिए अपना जवाब साझा करना चाहता था।

किसी संख्या के पूरक को खोजने के लिए, पहले उसके बाइनरी समतुल्य को खोजें। यहां, दशमलव संख्या 2को 0000 0010द्विआधारी रूप में दर्शाया गया है। अब inverting द्वारा अपने एक के पूरक लेना (सभी 1 के 0 में और सभी 0 के 1 में से) अपने द्विआधारी प्रतिनिधित्व के सभी अंक, जिसके परिणामस्वरूप होगा:

0000 0010 → 1111 1101

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

अब, चूंकि संख्याओं को 2 के पूरक के रूप में संग्रहीत किया जाता है (किसी संख्या को एक के पूरक के रूप में लेना), इसलिए इस द्विआधारी संख्या 1111 1101को दशमलव में प्रदर्शित करने के लिए , पहले हमें इसके 2 के पूरक को खोजने की आवश्यकता है, जो होगा:

1111 1101 → 0000 0010 + 1 → 0000 0011

यह 2 का पूरक है। बाइनरी नंबर का दशमलव प्रतिनिधित्व, है 0000 0011, है 3। और, चूंकि साइन बिट ऊपर वर्णित के रूप में एक था, इसलिए परिणामी उत्तर है -3

संकेत: यदि आप इस प्रक्रिया को ध्यान से पढ़ते हैं, तो आपने देखा होगा कि किसी के पूरक ऑपरेटर का परिणाम वास्तव में होता है, संख्या (ऑपरेंड - जिस पर यह ऑपरेटर लागू होता है) प्लस एक नकारात्मक चिन्ह के साथ। आप इसे अन्य नंबरों के साथ भी आज़मा सकते हैं।


दो बार क्यों जोड़ रहा है? मैं देख रहा हूं add, flip, add0010-> 0011-> 1100->1101
ब्रैडेन बेस्ट

1
यह फ्लिप है, फ्लिप, ऐड। 1 के पूरक के लिए पहले फ्लिप करें। और चूंकि, यह सिस्टम में 2 के पूरक में संग्रहीत है, जब आपको संख्या प्रदर्शित करने की आवश्यकता होती है, तो यह संग्रहीत संख्या के 2 के पूरक को दिखाएगा (यानी, दूसरा फ्लिप और ऐड)।
हिमांशु अग्रवाल

लेकिन फ्लिप (फ्लिप (2)) सिर्फ 2 नहीं होगा? 0010 1101 0010
ब्रैडेन बेस्ट

हाँ यह केवल 2 होगा। लेकिन जब से बिट्स को मेमोरी में स्टोर किया जाता है, तो सबसे महत्वपूर्ण बिट 1 था जो ऊपर दिए गए उत्तर में बताए अनुसार संख्या को बाद में नकारात्मक बना देगा।
हिमांशु अग्रवाल

1
आप जिस चीज का वर्णन कर रहे हैं और जिस चीज पर मैंने शोध किया है, यह एक दो का पूरक नहीं है, बल्कि एक "नियमित" पूरक, या एक बिटवाइज़ नहीं है। तर्क में, NOT 0 = 1और NOT 1 = 0। चार-बिट सिस्टम में, NOT 0011(3) = 1100(12 अहस्ताक्षरित, -4 हस्ताक्षरित)। मैं जो समझता हूं, दो के पूरक के रूप में परिभाषित किया गया है (NOT n) + 1, और बिट्स की संख्या की परवाह किए बिना किसी संख्या के नकारात्मक समकक्ष को खोजने के लिए उपयोग किया जाता है। इस प्रकार, 2c(5) = -5। देखें, अब यह सही समझ में आता है। जब तक आप इस ऑपरेशन को कहते हैं, तब तक यह है: एक बिटवाइज़ नहीं।
ब्रैडेन बेस्ट

4

int a = 4; Println (~ एक); परिणाम होगा: -5

जावा में किसी भी पूर्णांक का '~' नंबर 1 के पूरक का प्रतिनिधित्व करता है। उदाहरण के लिए मैं ~ 4 ले रहा हूं, जिसका अर्थ है बाइनरी प्रतिनिधित्व 0100। पहले, एक पूर्णांक की लंबाई चार बाइट्स है, अर्थात 4 * 8 (1 बाइट के लिए 8 बिट) = 32। तो सिस्टम मेमोरी 4 में अब 0000 0000 0000 0000 0000 0000 0100 0100 के रूप में दर्शाया गया है ~ ऑपरेटर उपरोक्त बाइनरी नं पर 1 का पूरक प्रदर्शन करेगा

अर्थात ११११ ११११ ११११ ११११ ११११ ११११ ११११ १११११-> १ का पूरक सबसे महत्वपूर्ण बिट का प्रतिनिधित्व करता है (या तो - या +) यदि यह १ है तो संकेत है '-' यदि यह 0 है तो संकेत '+' के अनुसार है यह हमारा परिणाम एक ऋणात्मक संख्या है, जावा में ऋणात्मक संख्याओं को 2 के पूरक रूप में संग्रहीत किया जाता है, अर्जित परिणाम को हमें 2 के पूरक में बदलना होगा (पहले 1 का पूरक प्रदर्शन करें और केवल 1 से 1 का पूरक जोड़ें)। सबसे महत्वपूर्ण बिट 1 को छोड़कर सभी एक शून्य हो जाएंगे (जो कि संख्या का हमारा संकेत प्रतिनिधित्व है, इसका मतलब है कि शेष 31 बिट्स 1111 1111 1111 1111 1111 1111 1111 1011 (~ ऑपरेटर का अर्जित परिणाम) 1000 0000 0000 0000 0000 0000 0000 0100 (1 का पूरक)

1 (2 का पूरक)

1000 0000 0000 0000 0000 0000 0101 अब परिणाम -5 है वीडियो के लिए इस लिंक को देखें <[java में बिट बुद्धिमान ऑपरेटरों] https://youtu.be/w4pJ4cGWe9Y


2

बस ...........

किसी भी संख्या के 2 के पूरक के रूप में हम सभी 1s को 0 में और इसके विपरीत 1 की गणना करके गणना कर सकते हैं।

यहाँ N = ~ N परिणाम देते हैं - (N + 1) हमेशा। क्योंकि सिस्टम डेटा को 2 के पूरक के रूप में संग्रहीत करता है जिसका अर्थ है कि यह इस तरह ~ N को संग्रहीत करता है।

  ~N = -(~(~N)+1) =-(N+1). 

उदाहरण के लिए::

  N = 10  = 1010
  Than ~N  = 0101
  so ~(~N) = 1010
  so ~(~N) +1 = 1011 

अब बिंदु वह है जहां से माइनस आता है। मेरी राय है कि हमारे पास 32 बिट रजिस्टर है जिसका मतलब है 2 ^ 31 -1 बिट ऑपरेशन में शामिल है और एक बिट को आराम करने के लिए जो पहले की गणना (पूरक) में परिवर्तित होता है जो साइन बिट के रूप में संग्रहीत होता है जो आमतौर पर 1 होता है। और हमें ~ 10 = -11 के रूप में परिणाम मिलता है।

~ (-११) = १०;

ऊपर सच है अगर प्रिंटफ ("% d", ~ 0); हमें परिणाम मिलता है: -1;

लेकिन परिणाम की तुलना में प्रिंटफ ("% u", ~ 0): 32 बिट मशीन पर 4294967295।


1

बिटवाइज़ पूरक ऑपरेटर (~) एक अपर ऑपरेटर है।

यह निम्नलिखित विधियों के अनुसार काम करता है

पहले यह दी गई दशमलव संख्या को उसके संबंधित बाइनरी मान में परिवर्तित करता है। 2 के मामले में यह पहली बार 2 से 0000 0010 (8 से 8 बिट बाइनरी नंबर) में परिवर्तित होता है।

फिर यह संख्या में सभी 1 को 0 में और सभी शून्य को 1 में परिवर्तित करता है, फिर संख्या 1111 1101 हो जाएगी।

यह -2 के पूरक का प्रतिनिधित्व करता है।

पूरक का उपयोग करके अहस्ताक्षरित मान को खोजने के लिए, अर्थात केवल 1111 1101 को दशमलव (= 4294967293) में बदलने के लिए हम मुद्रण के दौरान% u का उपयोग कर सकते हैं।


1

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

मानव दशमलव दुनिया के लिए: 01 का अर्थ है 1, -01 का अर्थ है -1, कंप्यूटर की द्विआधारी दुनिया के लिए: 101 का अर्थ है 5 यदि यह अहस्ताक्षरित है। 101 का अर्थ है (-4 + 1) यदि हस्ताक्षरित है जबकि हस्ताक्षरित अंक स्थिति x पर है। | एक्स

इसलिए 2 का फ़्लिप बिट = ~ 2 = ~ (010) = 101 = -4 + 1 = -3 यह भ्रम हस्ताक्षरित परिणाम (101 = -3) और असम्बद्ध परिणाम (101 = 5) को मिलाने से आता है।


1

tl; डॉ ~ बिट्स flips। परिणामस्वरूप संकेत बदल जाता है। ~2एक नकारात्मक संख्या ( 0b..101) है। उत्पादन के लिए एक नकारात्मक संख्या rubyप्रिंट -, तो के दो के पूरक ~2: -(~~2 + 1) == -(2 + 1) == 3। सकारात्मक संख्याएँ आउटपुट हैं जैसा कि है।

एक आंतरिक मूल्य है, और इसका स्ट्रिंग प्रतिनिधित्व है। सकारात्मक पूर्णांकों के लिए, वे मूल रूप से मेल खाते हैं:

irb(main):001:0> '%i' % 2
=> "2"
irb(main):002:0> 2
=> 2

बाद वाले के बराबर:

irb(main):003:0> 2.to_s
"2"

~आंतरिक मूल्य के बिट्स को फ़्लिप करता है। 2है 0b010~2है 0b..101। दो बिंदु ( ..) अनंत संख्या का प्रतिनिधित्व करते हैं 1। चूंकि परिणाम का सबसे महत्वपूर्ण बिट (MSB) है 1, परिणाम एक नकारात्मक संख्या है ((~2).negative? == true ) है। एक नकारात्मक संख्या rubyप्रिंट का उत्पादन करने के लिए -, फिर आंतरिक मूल्य के दो पूरक। दो के पूरक को बिट्स को फ़्लिप करके, फिर जोड़कर गणना की जाती है 1। दो का पूरक 0b..101है 3। जैसे की:

irb(main):005:0> '%b' % 2
=> "10"
irb(main):006:0> '%b' % ~2
=> "..101"
irb(main):007:0> ~2
=> -3

इसे योग करने के लिए, यह बिट्स को फ़्लिप करता है, जो संकेत को बदलता है। एक नकारात्मक संख्या को आउटपुट करने के लिए यह प्रिंट करता है -, फिर ~~2 + 1( ~~2 == 2)।

इस rubyतरह नकारात्मक संख्याओं का उत्पादन करने का कारण यह है, क्योंकि यह संग्रहीत मूल्य को पूर्ण मूल्य के दो पूरक के रूप में मानता है। दूसरे शब्दों में, जो संग्रहीत है वह है 0b..101। यह एक ऋणात्मक संख्या है, और जैसे कि यह एक दो का कुछ मूल्य का पूरक हैx । खोजने के लिए x, यह दो का पूरक है 0b..101। जो दो का पूरक है दो का पूरक है x। जो है x(जैसे ~(~2 + 1) + 1 == 2)।

यदि आप ~एक ऋणात्मक संख्या पर लागू होते हैं , तो यह बिट्स को प्रवाहित करता है (जो फिर भी संकेत बदलता है):

irb(main):008:0> '%b' % -3
=> "..101"
irb(main):009:0> '%b' % ~-3
=> "10"
irb(main):010:0> ~-3
=> 2

जो अधिक भ्रामक है वह है ~0xffffff00 != 0xff(या MSB के बराबर कोई अन्य मूल्य 1)। चलो इसे थोड़ा सरल करते हैं ~0xf0 != 0x0f:। ऐसा इसलिए है क्योंकि यह 0xf0एक सकारात्मक संख्या के रूप में व्यवहार करता है । जो वास्तव में समझ में आता है। तो, ~0xf0 == 0x..f0f। परिणाम एक नकारात्मक संख्या है। दो का पूरक है0x..f0f है 0xf1। इसलिए:

irb(main):011:0> '%x' % ~0xf0
=> "..f0f"
irb(main):012:0> (~0xf0).to_s(16)
=> "-f1"

यदि आप परिणाम के लिए बिटवाइज़ ऑपरेटरों को लागू नहीं करने जा रहे हैं, तो आप विचार कर सकते हैं ~ एक -x - 1ऑपरेटर के रूप में :

irb(main):018:0> -2 - 1
=> -3
irb(main):019:0> --3 - 1
=> 2

लेकिन यह यकीनन ज्यादा इस्तेमाल नहीं है।

एक उदाहरण मान लें कि आपको 8-बिट (सादगी के लिए) नेटमास्क दिया गया है, और आप संख्या की गणना करना चाहते हैं 0। आप बिट्स को फ़्लिप करके और कॉल करके bit_length( 0x0f.bit_length == 4) उनकी गणना कर सकते हैं । परंतु~0xf0 == 0x..f0f , इसलिए हमने बेकार बिट्स को काट दिया है:

irb(main):014:0> '%x' % (~0xf0 & 0xff)
=> "f"
irb(main):015:0> (~0xf0 & 0xff).bit_length
=> 4

या आप XOR ऑपरेटर ( ^) का उपयोग कर सकते हैं :

irb(main):016:0> i = 0xf0
irb(main):017:0> '%x' % i ^ ((1 << i.bit_length) - 1)
=> "f"

0

पहले हमें दिए गए अंकों को उसके बाइनरी अंकों में विभाजित करना होगा और फिर अंतिम बाइनरी अंकों में जोड़कर इसे उल्टा करना होगा। इस निष्पादन के बाद हमें पिछले अंक के विपरीत संकेत देना होगा, जिसे हम शिकायत ~ 2 = -3 स्पष्टीकरण पा रहे हैं। : 2 एस बाइनरी फॉर्म 11111101 में 00000010 परिवर्तन है यह लोगों का पूरक है, फिर तारीफ की गई 00000010 + 1 = 00000011 जो कि तीन और द्विआधारी Ie, -3 के द्विआधारी रूप है


0

बिट-वार ऑपरेटर एक यूनीरी ऑपरेटर होता है जो मेरे अनुभव और ज्ञान के अनुसार संकेत और परिमाण पद्धति पर काम करता है।

उदाहरण के लिए ~ 2 का परिणाम -3 होगा।

ऐसा इसलिए है क्योंकि बिट-वार ऑपरेटर सबसे पहले साइन और परिमाण में संख्या का प्रतिनिधित्व करेगा जो 0000 0010 (8 बिट ऑपरेटर) है जहां एमएसबी साइन बिट है।

फिर बाद में यह ऋणात्मक संख्या 2 हो जाएगी, जो -2 है।

-2 को संकेत और परिमाण में 1000 0010 (8 बिट ऑपरेटर) के रूप में दर्शाया गया है।

बाद में यह एलएसबी (1000 0010 + 1) में 1 जोड़ता है जो आपको 1000 0011 देता है।

जो -3 है।


0

जावास्क्रिप्ट टिल्ड (~) किसी के पूरक के लिए दिए गए मान को पूरा करता है - सभी बिट्स उल्टे होते हैं। वह सब टिल्ड करता है। यह हस्ताक्षरित नहीं है। यह न तो किसी मात्रा को जोड़ता है और न ही घटाता है।

0 -> 1
1 -> 0
...in every bit position [0...integer nbr of bits - 1]

जावास्क्रिप्ट जैसी उच्च-स्तरीय भाषाओं का उपयोग करने वाले मानक डेस्कटॉप प्रोसेसर पर, BASE10 हस्ताक्षरित अंकगणित सबसे आम है, लेकिन ध्यान रखें, यह एकमात्र प्रकार नहीं है। सीपीयू स्तर पर बिट्स कई कारकों के आधार पर व्याख्या के अधीन हैं। 'कोड' स्तर पर, इस मामले में जावास्क्रिप्ट के रूप में, उन्हें परिभाषा के अनुसार 32-बिट हस्ताक्षरित पूर्णांक के रूप में व्याख्या की जाती है (चलो इस से बाहर तैरते हैं)। इसे क्वांटम के रूप में सोचो, उन 32-बिट्स एक साथ सभी संभावित मूल्यों का प्रतिनिधित्व करते हैं। यह पूरी तरह से परिवर्तित लेंस पर निर्भर करता है जिसे आप उन्हें देखते हैं।

JavaScript Tilde operation (1's complement)

BASE2 lens
~0001 -> 1110  - end result of ~ bitwise operation

BASE10 Signed lens (typical JS implementation)
~1  -> -2 

BASE10 Unsigned lens 
~1  -> 14 

उपरोक्त सभी एक ही समय में सच हैं।


0

मूल रूप से कार्रवाई एक पूरक है एक निषेध नहीं।

यहाँ x = ~ x परिणाम देते हैं - (x + 1) हमेशा।

x = ~ 2

- (2 + 1)

-3

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