$ 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 연산자인 &를 사용해야 합니다.