답변:
음수 는 양수에 대한 2의 보수 로 저장됩니다 . 예를 들어 다음은 2의 보수에서 -2를 나타냅니다. (8 비트)
1111 1110
이것을 얻는 방법은 숫자의 이진 표현을 취하고 보수를 취하고 (모든 비트를 뒤집 음) 1을 더하는 것입니다. 두 개는 0000 0010으로 시작하고 비트를 뒤집 으면 1111 1101이됩니다. 하나를 추가하면 위의 결과를 얻습니다. 첫 번째 비트는 부호 비트이며 음수를 의미합니다.
따라서 ~ 2 = -3을 얻는 방법을 살펴 보겠습니다.
다시 두 가지가 있습니다.
0000 0010
모든 비트를 뒤집기 만하면 다음과 같이됩니다.
1111 1101
2의 보수에서 -3의 모양은 무엇입니까? 양수 3 : 0000 0011로 시작하여 모든 비트를 1111 1100으로 뒤집고 1을 추가하여 음수 값 (-3), 1111 1101이되도록합니다.
따라서 단순히 2의 비트를 뒤집 으면 2의 보수 표현 인 -3을 얻게됩니다.
다른 사람들이 언급 한 ~
것처럼 비트를 뒤집어 놓고 (1에서 0으로, 0에서 1로 변경) 2의 보수 가 사용되므로 결과를 얻습니다.
한 가지 더해야 할 점은 2의 보수가 사용되는 이유 입니다. 따라서 음수에 대한 연산이 양수에 대한 연산과 동일합니다. 0을 얻기 위해 추가해야 할 -3
숫자로 생각 3
하면이 숫자는 1101
임을 알 수 있습니다. 이진수 추가는 10이 아닌 2에 도달 할 때 1을 소지 한 초등학교 (10 진수) 추가와 같습니다. .
1101 +
0011 // 3
=
10000
=
0000 // lose carry bit because integers have a constant number of bits.
따라서 1101
됩니다 -3
, 당신이 얻을 비트 플립 0010
이있다.
이 질문에 대한 답변이 오래 전 게시 된 것을 알고 있지만 같은 답변을 공유하고 싶었습니다.
숫자의 보수를 찾으려면 먼저 이진수에 해당하는 것을 찾으십시오. 여기서 10 진수 는 이진 형식으로 2
표시됩니다 0000 0010
. 이제 이진 표현의 모든 숫자를 뒤집어 (모든 1을 0으로, 0을 모두 1로 뒤집 음) 1을 보완하면 다음과 같은 결과가 나타납니다.
0000 0010 → 1111 1101
이것은 10 진수 2의 보수입니다. 그리고 첫 번째 비트, 즉 부호 비트는 이진수에서 1이므로 부호는 저장된 숫자에 대해 음수 임을 의미합니다 . (여기서 언급 된 숫자는 2 가 아니라 2의 보수입니다).
이제 숫자는 2의 보수로 저장되므로 (1의 보수에 1을 더한 1을 차지함)이 이진수 1111 1101
를 10 진수 로 표시 하려면 먼저 2의 보수를 찾아야합니다.
1111 1101 → 0000 0010 + 1 → 0000 0011
이것은 2의 보수입니다. 이진수의 10 진수 표현은 0000 0011
입니다 3
. 그리고 부호 비트는 위에서 언급 한 것과 같으므로 결과 답은 -3
입니다.
힌트 : 이 절차를주의 깊게 읽으면, 보수 연산자의 결과는 실제로 숫자 (오퍼레이터-이 연산자가 적용되는 숫자)에 음수 부호를 더한 것임을 알 수 있습니다. 다른 번호로도 시도 할 수 있습니다.
add, flip, add
있습니다. 0010
-> 0011
-> 1100
->1101
0010
1101
0010
NOT 0 = 1
그리고 NOT 1 = 0
. 4 비트 시스템에서 NOT 0011
(3) = 1100
(12는 부호 없음, -4는 부호 없음) 내가 이해 한 바에 따르면 2의 보수는로 정의되며 (NOT n) + 1
비트 수에 관계없이 숫자의 음수 대응 부분을 찾는 데 사용됩니다. 따라서 2c(5) = -5
. 이제는 완벽하게 이해됩니다. 이 오퍼레이션을 호출하는 한, 비트 단위 NOT입니다.
int a = 4; System.out.println (~ a); 결과는 다음과 같습니다 .-5
Java에서 정수의 '~'는 1의 1의 보수를 나타냅니다. 예를 들어 나는 ~ 4를 취하고 있는데, 이것은 이진 표현 0100을 의미합니다. 첫째, 정수의 길이는 4 바이트, 즉 4 * 8 (1 바이트의 경우 8 비트) = 32입니다. 따라서 시스템 메모리 4에서 0000 0000 0000 0000 0000 0000 0000 0100으로 표시됩니다. ~ 연산자는 위의 바이너리에 대해 1의 보수를 수행합니다.
즉 1111 1111 1111 1111 1111 1111 1111 1011-> 1의 보수는 최상위 비트가 1이면 no (-또는 +)의 부호를 나타내고 0이면 부호는 '-'이고 0이면 부호는 '+'입니다 이 결과는 음수이며, 자바에서는 음수가 2의 보수 형식으로 저장됩니다. 획득 한 결과는 2의 보수로 변환해야합니다 (먼저 1의 보수를 수행하고 1을 1의 보수를 추가하십시오). 가장 중요한 비트 1을 제외한 모든 비트가 0이됩니다 (숫자의 부호 표시, 나머지 31 비트는 1111 1111 1111 1111 1111 1111 1111 1011 (~ 연산자의 획득 결과) 1000 0000 0000 0000 0000 0000 0000 0100 (1의 보수)
1000 0000 0000 0000 0000 0000 0000 0101 이제 결과는 -5입니다. 비디오에 대한이 링크를 확인 하십시오.
간단히 ...........
어떤 수의 2의 보수로, 우리는 1을 더하는 것보다 모든 1을 0으로 그리고 그 반대로 반전함으로써 계산할 수 있습니다.
여기서 N = ~ N은 항상 결과를 생성합니다. 시스템은 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 인 부호 비트로 저장된 초기 계산 (보완)에서 변경된 1 비트를 쉬게한다고 가정합니다. 그리고 우리는 ~ 10 = -11로 결과를 얻습니다.
~ (-11) = 10;
printf ( "% d", ~ 0); 우리는 결과를 얻는다 : -1;
그러나 32 비트 시스템에서 printf ( "% u", ~ 0) 결과 : 4294967295보다.
비트 보수 연산자 (~)는 단항 연산자입니다.
다음 방법에 따라 작동합니다
먼저 주어진 10 진수를 해당 이진 값으로 변환합니다 .2의 경우 2를 0000 0010 (8 비트 이진수)으로 먼저 변환합니다.
그런 다음 숫자의 모든 1을 0으로 변환하고 모든 0을 1로 변환하면 숫자는 1111 1101이됩니다.
이것이 2의 보수 -3을 나타냅니다.
보수를 사용하여 부호없는 값을 찾으려면, 즉 1111 1101을 10 진수 (= 4294967293)로 변환하기 만하면 인쇄 중에 % u를 사용할 수 있습니다.
나는 대부분의 사람들에게 혼란 부분은 십진수와 부호있는 이진수의 차이점에서 비롯된 것이라고 생각합니다.
인간 십진 세계의 경우 : 01은 1을, -01은 -1을, 컴퓨터의 이진 세계는 101을 부호가없는 경우 5를 의미합니다. 101은 부호있는 숫자가 x 위치에있는 동안 부호가 있으면 (-4 + 1)을 의미합니다. | 엑스
따라서 2의 뒤집힌 비트 = ~ 2 = ~ (010) = 101 = -4 + 1 = -3 혼동은 부호있는 결과 (101 = -3)와 정렬되지 않은 결과 (101 = 5)를 혼합하여 발생합니다.
tl; dr ~
은 비트를 뒤집습니다. 결과적으로 부호가 변경됩니다. ~2
음수 ( 0b..101
)입니다. 음수 ruby
인쇄 를 출력하려면 -
2의 보수 ~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
prints 를 출력하려면 -
내부 값의 2의 보수입니다. 2의 보수는 비트를 뒤집은 다음을 추가하여 계산됩니다 1
. 2의 보수는 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
음수를 출력 하는 이유 는 저장된 값을 절대 값의 2의 보수로 취급하기 때문입니다. 즉, 저장되는 것은 0b..101
입니다. 음수이며, 따라서 일부 값의 2의 보수입니다 x
. 를 찾으려면 x
2의 보수를 수행 0b..101
합니다. 2의 보수 2의 보수입니다 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
. 결과는 음수입니다. 2의 보수는 0x..f0f
입니다 0xf1
. 그래서:
irb(main):011:0> '%x' % ~0xf0
=> "..f0f"
irb(main):012:0> (~0xf0).to_s(16)
=> "-f1"
경우 당신이 결과에 비트 연산자를 적용하지 않을거야, 당신은 고려할 수 ~
A와 -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"
먼저 우리는 주어진 숫자를 이진수로 나누고 마지막 이진수를 더해서 뒤집어 야합니다. : 2s 이진 형식은 00000010이며 11111101로 변경됩니다. 이것은 보완되는 것입니다.
비트 연산자는 내 경험과 지식에 따라 부호와 크기 방법으로 작동하는 단항 연산자입니다.
예를 들어 ~ 2는 -3이됩니다.
비트 단위 연산자는 먼저 부호와 크기가 0000 0010 (8 비트 연산자) 인 숫자를 나타 내기 때문에 MSB는 부호 비트입니다.
그런 다음 나중에 -2 인 음수 2를 사용합니다.
-2는 부호와 크기가 1000 0010 (8 비트 연산자)으로 표시됩니다.
나중에 LSB (1000 0010 + 1)에 1을 추가하여 1000 0011을 제공합니다.
어느 것이 -3입니다.
자바 스크립트 물결표 (~)는 주어진 값을 보수로 강제합니다. 모든 비트가 반전됩니다. 이 모든 것이 물결표입니다. 의견이 없다. 수량을 더하거나 빼지 않습니다.
0 -> 1
1 -> 0
...in every bit position [0...integer nbr of bits - 1]
JavaScript와 같은 고급 언어를 사용하는 표준 데스크탑 프로세서에서는 BASE10 부호있는 산술이 가장 일반적이지만 유일하지는 않습니다. CPU 레벨의 비트는 여러 가지 요인에 따라 해석 될 수 있습니다. '코드'수준 (이 경우 JavaScript)에서는 정의에 따라 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
위의 모든 내용이 동시에 적용됩니다.