비트 보수 연산자 (~ 틸드)는 어떻게 작동합니까?


답변:


281

음수 는 양수에 대한 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을 얻게됩니다.

보수 연산자 (~) JUST FLIPS BITS. 이 비트들을 해석하는 것은 기계에 달려 있습니다.


43
또 다른 언급은 1을 추가하기 전에 플립을 1s 보수라고합니다.
Chris S

3
그것은 하나의 보완과 두 개의 보완을 모르는 다른 사람들을 도울 수 있습니다. 여기에 대해 읽어보십시오. en.wikipedia.org/wiki/Ones%27_complement en.wikipedia.org/wiki/Two%27s_complement
Sai

1
비트 NOT 연산자가 아닙니까?
Braden Best

3
기계는 높은 양수 대신 두 개의 음수를 얻는다는 것을 어떻게 알 수 있습니까? 해당 언어의 유형 시스템으로 인해 유형이 부호있는 정수와 부호없는 것을 나타내는 것입니까?
GL2014

@ GL2014 나는 당신이 당신의 자신의 질문에 대답했다고 생각합니다. 내 이해에 따르면, 기계가 처음부터 작동하도록 설계되었습니다.
geekidharsh

40

~ 값의 비트를 뒤집습니다.

숫자가 비트 단위로 표시되는 방식과 관련이있는 이유 ~2는 무엇입니까? -3숫자는 2의 보수 로 표시됩니다 .

2는 이진수 값입니다

00000010

그리고 ~ 2는 비트를 뒤집어서 값이 다음과 같습니다.

11111101

-3의 이진 표현입니다.


2
11111101 == 10 진수 253 ​​대 -3이 아닙니까?
AKS

10
부호있는 정수 또는 부호없는 정수를 나타내는 지 여부에 따라 다릅니다.
driis

18

다른 사람들이 언급 한 ~것처럼 비트를 뒤집어 놓고 (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이있다.


8

이 작업은 부정이 아닌 보완입니다.

~ 0 = -1이라고 생각하고 거기서부터 작업하십시오.

부정 알고리즘은 "보완, 증분"입니다.

알고 계십니까? 역수 대칭 인 "1의 보수"도 있으며 0과 -0을 모두 갖습니다.


6

이 질문에 대한 답변이 오래 전 게시 된 것을 알고 있지만 같은 답변을 공유하고 싶었습니다.

숫자의 보수를 찾으려면 먼저 이진수에 해당하는 것을 찾으십시오. 여기서 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
Braden Best

1
뒤집기, 뒤집기, 추가 1의 보수를 먼저 뒤집습니다. 또한 시스템에 2의 보수로 저장되므로 숫자를 표시해야 할 때 저장된 숫자의 2의 보수 (예 : 두 번째 반전 및 추가)가 표시됩니다.
Himanshu Aggarwal

그러나 flip (flip (2))이 2가되지 않습니까? 0010 1101 0010
Braden Best

예, 2 만됩니다. 그러나 비트가 메모리에 저장 될 때 최상위 비트는 1이되었으므로 위의 답변에서 설명한 것처럼 나중에 음수로 만듭니다.
Himanshu Aggarwal

1
당신이 묘사하고 연구 한 모든 것에서, 이것은 2의 보수가 아니라 "정규적인"보수 또는 비트 NOT입니다. 논리에서, NOT 0 = 1그리고 NOT 1 = 0. 4 비트 시스템에서 NOT 0011(3) = 1100(12는 부호 없음, -4는 부호 없음) 내가 이해 한 바에 따르면 2의 보수는로 정의되며 (NOT n) + 1비트 수에 관계없이 숫자의 음수 대응 부분을 찾는 데 사용됩니다. 따라서 2c(5) = -5. 이제는 완벽하게 이해됩니다. 이 오퍼레이션을 호출하는 한, 비트 단위 NOT입니다.
Braden Best

4

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의 보수)

1 (2의 보수)

1000 0000 0000 0000 0000 0000 0000 0101 이제 결과는 -5입니다. 비디오에 대한이 링크를 확인 하십시오.


2

간단히 ...........

어떤 수의 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보다.


1

비트 보수 연산자 (~)는 단항 연산자입니다.

다음 방법에 따라 작동합니다

먼저 주어진 10 진수를 해당 이진 값으로 변환합니다 .2의 경우 2를 0000 0010 (8 비트 이진수)으로 먼저 변환합니다.

그런 다음 숫자의 모든 1을 0으로 변환하고 모든 0을 1로 변환하면 숫자는 1111 1101이됩니다.

이것이 2의 보수 -3을 나타냅니다.

보수를 사용하여 부호없는 값을 찾으려면, 즉 1111 1101을 10 진수 (= 4294967293)로 변환하기 만하면 인쇄 중에 % u를 사용할 수 있습니다.


1

나는 대부분의 사람들에게 혼란 부분은 십진수와 부호있는 이진수의 차이점에서 비롯된 것이라고 생각합니다.

인간 십진 세계의 경우 : 01은 1을, -01은 -1을, 컴퓨터의 이진 세계는 101을 부호가없는 경우 5를 의미합니다. 101은 부호있는 숫자가 x 위치에있는 동안 부호가 있으면 (-4 + 1)을 의미합니다. | 엑스

따라서 2의 뒤집힌 비트 = ~ 2 = ~ (010) = 101 = -4 + 1 = -3 혼동은 부호있는 결과 (101 = -3)와 정렬되지 않은 결과 (101 = 5)를 혼합하여 발생합니다.


1

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)입니다. 음수 rubyprints 를 출력하려면 -내부 값의 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. 를 찾으려면 x2의 보수를 수행 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"

0

먼저 우리는 주어진 숫자를 이진수로 나누고 마지막 이진수를 더해서 뒤집어 야합니다. : 2s 이진 형식은 00000010이며 11111101로 변경됩니다. 이것은 보완되는 것입니다.


0

비트 연산자는 내 경험과 지식에 따라 부호와 크기 방법으로 작동하는 단항 연산자입니다.

예를 들어 ~ 2는 -3이됩니다.

비트 단위 연산자는 먼저 부호와 크기가 0000 0010 (8 비트 연산자) 인 숫자를 나타 내기 때문에 MSB는 부호 비트입니다.

그런 다음 나중에 -2 인 음수 2를 사용합니다.

-2는 부호와 크기가 1000 0010 (8 비트 연산자)으로 표시됩니다.

나중에 LSB (1000 0010 + 1)에 1을 추가하여 1000 0011을 제공합니다.

어느 것이 -3입니다.


0

자바 스크립트 물결표 (~)는 주어진 값을 보수로 강제합니다. 모든 비트가 반전됩니다. 이 모든 것이 물결표입니다. 의견이 없다. 수량을 더하거나 빼지 않습니다.

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 

위의 모든 내용이 동시에 적용됩니다.


0

기본적으로 행동은 부정이 아닌 보완입니다.

여기서 x = ~ x는 항상-(x + 1) 결과를 생성합니다.

x = ~ 2

-(2 + 1)

-삼

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.