回答:
〜演算子はビット単位のNOT演算子です。これを使用することは、数値を否定することとは異なります。
ウィキペディア、ビット単位のNOT演算は、値マイナス1の2の補数をとることに等しいです。
NOT x = −x − 1
2進数を否定することは、その2の補数の値を取ることと同等です。
〜NOT演算子=を使用して、その補数の値を取ります。
簡単に言えば、〜はバイナリ表現のすべてのビットを反転させるだけです。
あなたの例:
33(10進数)= 0x00100001(8ビットバイナリ)
〜33 =〜0x00100001 = 0x11011110 = -34(10進数)
または、10進算術では、〜x = -x-1式を使用します。
〜33 = -33-1 = -34
そして
〜255 = -255-1 = -256
問題は〜がビット単位の演算子であることです。したがって、おそらくあなたが意図するよりも多くのビットを否定しています。結果を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
また、&を使用して、ビット単位のand演算子を使用して、開始時のすべてのffを回避する必要があります。
~
(算術)オペレータは、すべてのビットを反転させ、それがビット単位の否定演算子と呼ばれます:
! ~ logical and bitwise negation
したがって、コンテキストが算術である場所では、すべてのビットをゼロとして、すべてのビットを1として数値を変更します。A $(( ~0 ))
は、数値表現のすべてのビット(今日では通常64ビット)をすべて1に変換します。
$ printf '%x\n' "$(( ~0 ))"
ffffffffffffffff
すべて1の数は、負の数(最初のビット1
)1
または単にとして解釈され-1
ます。
$ printf '%x\n' "-1"
ffffffffffffffff
$ echo "$(( ~0 ))"
-1
同じことが他のすべての数値にも起こり$(( ~1 ))
ます。たとえば、すべてのビットを反転します。
$ printf '%x\n' "$(( ~1 ))"
fffffffffffffffe
または、バイナリで: 1111111111111111111111111111111111111111111111111111111111111110
これは、2の表現の数値として解釈されます:
$ 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