"$ ((~ 33))" उत्पादन -34 क्यों करता है?


12
$ echo $(( 255 ))
255
$ echo $(( 33 ))
33
$ echo $(( ~33 ))
-34
$ echo $(( ~255 ))
-256
$ 

और मेरी गिरी है:

$ uname -a
Linux HOSTNAME 3.2.0-40-generic-pae #64-Ubuntu SMP Mon Mar 25 21:44:41 UTC 2013 i686 i686 i386 GNU/Linux

प्रश्न: ~ संख्या AFAIK की उपेक्षा के लिए है। लेकिन क्यों करता है ~33उत्पादन -34और क्यों करता है ~255उत्पादन -256?


2
बिटवाइज नेगेटिव, अंकगणित निषेध ( -x ) के साथ भ्रमित नहीं होना
चेपनर

जवाबों:


21

मार के आदमी पेज कहते हैं:

   ! ~    logical and bitwise negation

हस्ताक्षरित संख्याएं आमतौर पर दो के पूरक प्रतिनिधित्व में संग्रहीत होती हैं :

...
-4 = 1100
-3 = 1101
-2 = 1110
-1 = 1111
 0 = 0000
 1 = 0001
 2 = 0010
 3 = 0011
...

इसका मतलब है कि यदि आप संख्या को 2 की तरह लेते हैं तो इसे बिटवाइस की व्याख्या 0010 के रूप में की जाती है। बिटवाइज़ नकार के बाद यह 1101 हो जाता है, जो -3 का प्रतिनिधित्व है।


10

यह दो पूरक अंकगणित का परिणाम है।

~एक बिटवाइज़ नेगेटिव है जो सभी बिट्स को संचालित करता है। बिट्स के सभी inverting और 1. जोड़कर दो पूरक अंकगणितीय कार्य करता है। जब से आप केवल बिट्स को फ़्लिप कर चुके हैं, लेकिन एक को नहीं जोड़ा गया है, आपको एक ही नंबर मिलता है, उल्टा, माइनस एक।

विकिपीडिया के दो पूरक यहाँ पर एक अच्छा लेख है

उदाहरण के तौर पे:

  • बाइनरी में 3 है 0011
  • -3 (दो के पूरक) बाइनरी है 1101
  • इन्वर्टिंग 0011आपको देता है 1100, जो -4 है, क्योंकि आपने 1 नहीं जोड़ा है।

3

~ ऑपरेटर बिटवाइज़ नहीं ऑपरेटर है। इसका उपयोग करना किसी संख्या को नकारने के समान नहीं है।

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

X = xx - 1 नहीं

एक द्विआधारी संख्या की उपेक्षा करना इसके दो-पूरक मूल्य लेने के बराबर है।

~ नहीं ऑपरेटर का उपयोग करना = इसका एक-पूरक मूल्य लें।

सरल शब्दों में, ~ बस बाइनरी प्रतिनिधित्व के सभी बिट्स को फ़्लिप करता है

आपके उदाहरणों के लिए:

33 (दशमलव) = 0x00100001 (8-बिट बाइनरी)

~ 33 = ~ 0x00100001 = 0x11011110 = -34 (दशमलव)

या दशमलव अंकगणित में, ~ x = -x - 1 सूत्र का उपयोग करके:

~ 33 = -33 - 1 = -34

तथा

~ 255 = -255 - 1 = -256


1

समस्या यह है कि ~ एक बिट-वार ऑपरेटर है। इसलिए आप जितना इरादा रखते हैं उससे अधिक बिट्स को नकार रहे हैं। आप परिणामों को हेक्स में परिवर्तित करके इसे बेहतर देख सकते हैं जैसे:

result_in_hex=$(printf "%x" $(( ~33 ))); echo $result_in_hex
ffffffffffffffde

बनाम जो आपके पास था:

result_in_dec=$(printf "%d" $(( ~33 ))); echo $result_in_dec
-34

मैं मान रहा हूं कि आप 0x33 को नकारना चाहते हैं। अगर ऐसा है तो यह काम करेगा:

result_in_hex=$(printf "%2x" $(( ( ~ 0x33 ) & 0xFF))); echo $result_in_hex
cc

आपको शुरुआत में सभी ff से बचने के लिए बिट-वार और ऑपरेटर का भी उपयोग करना होगा।


1

~(गणित) ऑपरेटर सभी बिट्स flips , यह बिटवाइज़ निषेध ऑपरेटर कहा जाता है:

! ~    logical and bitwise negation

इसलिए, उन जगहों पर जहां संदर्भ अंकगणित है, यह एक संख्या को सभी बिट्स के साथ शून्य के रूप में सभी बिट्स में बदलता है। एक $(( ~0 ))संख्या प्रतिनिधित्व के सभी बिट्स (आमतौर पर आजकल 64 बिट्स) को सभी लोगों तक पहुंचाता है।

$ printf '%x\n' "$(( ~0 ))"
ffffffffffffffff

सभी लोगों के साथ एक संख्या को नकारात्मक संख्या (पहले बिट 1) 1, या बस के रूप में व्याख्या की जाती है -1

$ printf '%x\n' "-1"
ffffffffffffffff

$ echo "$(( ~0 ))"
-1

वही अन्य सभी संख्याओं के लिए होता है, उदाहरण के लिए: $(( ~1 ))सभी बिट्स को फ़्लिप करता है:

$ printf '%x\n' "$(( ~1 ))"
fffffffffffffffe

या, बाइनरी में: 1111111111111111111111111111111111111111111111111111111111111110

जो, दो के प्रतिनिधित्व में एक संख्या के रूप में व्याख्या की गई है:

$ echo "$(( ~1 ))"
-2

सामान्य तौर पर, मानव गणित समीकरण वह है $(( ~n ))जो समान है$(( -n-1 ))

$ n=0    ; echo "$(( ~n )) $(( -n-1 ))"
-1 -1

$ n=1    ; echo "$(( ~n )) $(( -n-1 ))"
-2 -2

$ n=255  ; echo "$(( ~n )) $(( -n-1 ))"
-256 -256

और (आपका प्रश्न):

$ n=33   ; echo "$(( ~n )) $(( -n-1 ))"
-34 -34

0

पहले आपको यह समझना होगा कि 33 एक 32 बिट्स या 64 बिट्स संख्या है।

संयोजकता के लिए मैं एक आठ बिट संख्या (= 1 बाइट) लेता हूं

दशमलव 33 आठ बिट्स में है: 00100001, बिट्स को फ्लिप करने के परिणामस्वरूप 11011110 होता है।

क्योंकि उच्च क्रम बिट 1 है, यह एक ऋणात्मक संख्या है।

एक ऋणात्मक संख्या को प्रिंट करना, सिस्टम एक ऋण चिह्न को प्रिंट करता है और फिर ऋणात्मक संख्या पर दो का पूरक करता है।

दो का पूरक है: बिट्स को फ़्लिप करना और 1 जोड़ना।

११०११११० ==> ००१००००१ ==> १ = १> ००१०००१ का परिणाम माइनस साइन के पीछे दशमलव ३४ में है।

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