"$(( ~33 ))"가 -34를 생성하는 이유는 무엇입니까?

"$(( ~33 ))"가 -34를 생성하는 이유는 무엇입니까?
$ 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

답변1

Bash 매뉴얼 페이지는 다음과 같이 말합니다.

   ! ~    logical and bitwise negation

서명된 숫자는 일반적으로 다음 위치에 저장됩니다.2의 보수표현하다:

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

즉, 2와 같은 숫자를 취하면 비트 단위로 0010으로 해석됩니다. 비트 부정을 하면 1101이 되는데, 이는 -3을 표현한 것이다.

답변2

이는 2의 보수 연산의 결과입니다.

~이는 비트 단위 부정으로, 연산 중인 모든 비트를 반전시킵니다. 2의 보수 연산은 모든 비트를 반전시키고 1을 더하는 방식으로 작동합니다. 비트만 뒤집었을 뿐 1을 더하지 않았기 때문에 반전 후에 1을 뺀 동일한 숫자를 얻게 됩니다.

Wikipedia에는 ​​2의 보수에 대한 좋은 기사가 있습니다.여기.

예를 들어:

  • 이진수로 3은0011
  • -3 in (2의 보수) 이진수는1101
  • 반전하면 아직 1을 추가하지 않았으므로 -4 0011가 됩니다 .1100

답변3

~ 연산자는 비트 NOT 연산자입니다. 그것을 사용하는 것은 숫자를 부정하는 것과 다릅니다.

~에서위키피디아, 비트별 NOT 연산은 값의 2의 보수에서 1을 빼는 것과 같습니다.

x = −x − 1이 아님

이진수를 부정하는 것은 2의 보수 값을 취하는 것과 같습니다.

~ NOT 연산자 =를 사용하여 보수 값을 가져옵니다.

간단히 말해서,~ 이진 표현의 모든 비트를 뒤집습니다..

예를 들어:

33(십진수) = 0x00100001(8비트 이진수)

~33 = ~0x00100001 = 0x11011110 = -34(십진수)

또는 소수 연산에서는 ~x = -x - 1 공식을 사용합니다.

~33 = -33 - 1 = -34

그리고

~255 = -255 - 1 = -256

답변4

문제는 ~가 비트 연산자라는 것입니다. 따라서 예상보다 더 많은 비트를 부정하고 있습니다. 결과를 16진수로 변환하면 이를 더 잘 볼 수 있습니다. 예를 들면 다음과 같습니다.

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를 피하려면 비트 AND 연산자인 &를 사용해야 합니다.

관련 정보