~ x + ~ y == ~ (x + y)는 항상 거짓입니까?


153

이 코드는 항상 거짓으로 평가됩니까? 두 변수 모두 2의 보수 부호있는 정수입니다.

~x + ~y == ~(x + y)

조건을 만족하는 숫자가 있어야한다고 생각합니다. 나는 사이의 숫자를 테스트하려 -5000하고 5000있지만, 결코 이루어지지 평등. 조건에 대한 해를 찾기 위해 방정식을 설정하는 방법이 있습니까?

하나를 다른 것으로 바꾸면 프로그램에 교활한 버그가 발생합니까?


6
증명이나 무언가를 원하십니까?
— Alvin Wong

26
부호있는 정수 오버플로의 경우 기술적으로 정의되지 않은 동작입니다. 따라서 true절대 2의 보수를 가정 할 수없는 경우에도 반환 할 수 있습니다.
— Mysticial

1
@AlvinWong 네 설명이 좋을 것입니다
— Steve

1
@Steve : 모든 조합에서 모든 일반적인 용의자 (-1, 0, 1, 2 등)를 시도했으며 작은 단어 크기의 문제를 "해결"하려는 시도 ( 3 비트? 4 비트?). 그것은 우리가 누군가가 먼저 돈을 벌려고 노력하지 않은 것을 얻도록 돕는 것이 아니라는 것을 우리에게 확신시키는 데 도움이 될 것입니다. :)
— sarnold 2016 년

4
@AlexLockwood 처음 질문을 게시했을 때 질문에 "숙제"로 태그를 지정하면 사람들이 문제를 해결하는 데 도움이되는 힌트를 제공 ( "숙제"태그 상태에 대한 설명으로)하고 답변을 제공한다고 가정했습니다. 그렇기 때문에 문제의 질문을 분명하게 물었습니다.
— Steve

답변:


237

모순을 위해 다음 x과 같은 일부 y(mod 2 n ) 가 존재한다고 가정하십시오.

~(x+y) == ~x + ~y

2의 보수 *로 우리는

      -x == ~x + 1
<==>  -1 == ~x + x

이 결과를 주목하면

      ~(x+y) == ~x + ~y
<==>  ~(x+y) + (x+y) == ~x + ~y + (x+y)
<==>  ~(x+y) + (x+y) == (~x + x) + (~y + y)
<==>  ~(x+y) + (x+y) == -1 + -1
<==>  ~(x+y) + (x+y) == -2
<==>  -1 == -2

따라서 모순입니다. 따라서 ~(x+y) != ~x + ~y모든 x및 y(mod 2 n )에 대해.


* 1의 보수 산술을 가진 기계에서, 평등은 실제로 모두 x와에 대해 사실을 유지한다는 것이 흥미 롭습니다 y. 이것은 하나의 보완 아래에 있기 때문 ~x = -x입니다. 따라서 ~x + ~y == -x + -y == -(x+y) == ~(x+y).


47
물론 C는이 동작을 요구하지 않습니다. 2의 보수 표현이 필요하지 않기 때문입니다.
— Billy ONeal

12
BTW, 평등은 진정한 1의 보수합니다. NOT 연산은 일반적으로 숫자에 대해 실제로 정의되지 않으므로 NOT과 덧셈을 혼합하면 숫자 표시에 따라 다른 동작이 발생합니다.
— nhahtdh 2016 년

9
하나는 부호없는 정수에 대한 문제를 다시 언급 할 수 있으며 두 개의 보수는 전혀 작동하지 않습니다.
— R .. GitHub 중지 지원 얼음

5
이럴가, 심지어 간단한 : ~x == -(x+1)그래서 ~(x+y) == ~x + ~y의미 -(x+y+1) == -(x+1) + -(y+1)의미-1 == -2
— BlueRaja - 대니 Pflughoeft

7
@BillyONeal, 걱정하지 마십시오. 농담 만하고 당신이 그것을 언급 해 주셔서 감사합니다 :). 보완적인 산술을 수행하는 기계를 만나는 날에 음료를 사 줄 것입니다 ... 어떻게 소리가 나는가? haha
— Alex Lockwood

113

2의 보완

온 광대 한 경우 컴퓨터의 대부분, x정수, 다음 -x과 같이 표현된다 ~x + 1. 마찬가지로 ~x == -(x + 1). 방정식 에서이 substution을 만들면 다음과 같이됩니다.

  • ~ x + ~ y == ~ (x + y)
  • -(x + 1) +-(y + 1) =-((x + y) + 1)
  • -x-y-2 = -x-y-1
  • -2 = -1

모순이므로 ~x + ~y == ~(x + y)항상 false 입니다.


즉, pedants는 C가 2의 보수를 요구하지 않는다는 것을 지적 할 것이므로 우리도 고려해야합니다 ...

보완

에서 1의 보수 , -x간단하게 표현된다 ~x. 0은 모두 0 +0과 ( -1 -0) 표현 을 모두 갖는 특별한 경우 이지만 IIRC, C는 +0 == -0비트 패턴이 다른 경우에도 필요 하므로 문제가되지 않습니다. 그냥 교체 ~와 함께 -.

  • ~ x + ~ y == ~ (x + y)
  • -x + (-y) =-(x + y)

이는 사실 모두 x와 y.


13
실제로 2의 보수와 1의 보수를 모두 동일한 근거로 고려하는 답은 +1입니다.
— CVn

13
@ dan04, +0 == -0. 마지막으로 C.에서 의미있는 것 :)
— Alex Lockwood

32

단지 오른쪽 모두의 비트 고려 x하고 y(IE를합니다. x == 13인 1101기본 2, 우리는, 마지막 비트에 보일 것이다 1다음 네 가지 경우가 있습니다)

x = 0, y = 0 :

LHS : ~ 0 + ~ 0 => 1 + 1 => 10
RHS : ~ (0 + 0) => ~ 0 => 1

x = 0, y = 1 :

LHS : ~ 0 + ~ 1 => 1 + 0 => 1
RHS : ~ (0 + 1) => ~ 1 => 0

x = 1, y = 0 :

숙제이기 때문에 나는 이것을 당신에게 맡길 것입니다 (힌트 : x와 y가 바뀌었을 때의 것과 동일합니다).

x = 1, y = 1 :

이것도 당신에게 맡기겠습니다.

가능한 한 입력이 주어지면 방정식의 왼쪽과 오른쪽에서 가장 오른쪽 비트가 항상 다름을 보여줄 수 있습니다. 따라서 양쪽 비트가 뒤집힌 비트가 적어도 있기 때문에 양쪽이 같지 않다는 것을 증명했습니다 서로로부터.


27

비트 수가 n 인 경우

~x = (2^n - 1) - x
~y = (2^n - 1) - y


~x + ~y = (2^n - 1) +(2^n - 1) - x - y =>  (2^n + (2^n - 1) - x - y ) - 1 => modulo: (2^n - 1) - x - y - 1.

지금,

 ~(x + y) = (2^n - 1) - (x + y) = (2^n - 1) - x - y.

따라서 그들은 항상 1의 차이로 불평등합니다.


4
@nhahtdh 및 ~고정되지 않은 너비 숫자에 대한 작업을 어떻게 정의 합니까?
— hamstergene 2018 년

1
나는이 대답을이 비트 수로 주어서 수업에서 배운 내용과 쉽게 연관시킬 수 있습니다. ~ x는 숫자를 나타내는 데 사용되는 비트 수 n에 크게 의존합니다. 따라서 이것을 실험적으로 검증하려고 할 때 하나를 고수하는 것이 합리적입니다.
— Karthik Kumar Viswanathan

1
@ hamstergene : 나는 비트 수가 고정되어 있다는 것을 알고 있지만 내 요점은 그 양 (8, 16 등) 일 필요는 없다는 것입니다.
— nhahtdh 2016 년

1
이것들은 답을 검증하기위한 프로그램을 작성하기 쉬운 값입니다. ~ x와 ~ y가 주어진 것과 일치하도록 쓰여있는 한, 모든 n에서 작동합니다.
— Karthik Kumar Viswanathan

1
@ hamstergene : 증거에 문제가 없습니다. 숫자가 그 경우에만 작동한다는 잘못된 의미를 나타냅니다.
— nhahtdh 2016 년

27

힌트:

x + ~x = -1(모드 2n )

질문의 목표가 (C-read-the-C- 사양 기술이 아닌) 수학을 테스트한다고 가정하면 대답을 얻을 수 있습니다.


2
2의 보수 기계에서만. (C 표준은 필요하지 않습니다)
— 빌리 ONeal에게

12
@ 빌리 (Billy) : "두 사람 만"이라고 말하는 것과 같습니다.
— dan04

2
@ dan04 : 아뇨, 그렇지 않습니다. 나는 서명 된 모든 규모와 보완적인 표현이 세상에서 사라 졌다고 말하고 싶습니다. 그러나 나는 그렇게 말하는 것이 잘못되었을 것입니다. C 표준에서는 그러한 가정을 할 수 없습니다. 따라서 나는 그 가정을하는 코드가 대부분 나쁜 코드라고 말할 것이다. (특히 비트 트위들 링보다 부호있는 숫자를 엉망으로 만드는 더 나은 방법이있을 때, 특히 부호없는 숫자가 아마도 대부분의 시간에 더 나은 선택 일 때)
— Billy ONeal

10

1과 2, 그리고 심지어 42의 보수에서, 이것은 증명 될 수 있습니다 :

~x + ~y == ~(x + a) + ~(y - a)

이제 a = y우리는 :

~x + ~y == ~(x + y) + ~(y - y)

또는:

~x + ~y == ~(x + y) + ~0

따라서 2의 보수에서 ~0 = -1 에서 제안은 거짓입니다.

그 보완책 ~0 = 0에서 제안은 사실입니다.


7

Dennis Ritchie의 저서에 따르면 C는 기본적으로 2의 보수를 구현하지 않습니다. 따라서 귀하의 질문이 항상 사실이 아닐 수도 있습니다.


5

시키는 것은 MAX_INT로 나타내는 INT 수 011111...111(그러나 많은 비트에있다). 그럼 당신은 알고, ~x + x = MAX_INT그리고 ~y + y = MAX_INT그렇게 때문에 당신이 차이 것을 확실히 알게 될 것이다, ~x + ~y그리고 ~(x + y)이다 1.


5

C는 2의 보수가 구현되는 것을 요구하지 않습니다. 그러나 부호없는 정수의 경우 비슷한 논리가 적용됩니다. 이 논리에서 차이는 항상 1입니다!


3

물론 C는 2의 보수 표현이 필요하지 않기 때문에이 동작이 필요하지 않습니다. 예를 들어 ~x = (2^n - 1) - x& ~y = (2^n - 1) - y는이 결과를 얻습니다.


0

아, 기본적인 이산 수학!

De Morgan의 법칙을 확인하십시오

~x & ~y == ~(x | y)

~x | ~y == ~(x & y)

부울 증명에 매우 중요합니다!


그냥 틀렸어 C +에서 덧셈, * 곱하기 및 부울 또는 or 및.
— nalply 2016 년

부정확하게 잘못된 연산자를 지적 해 주셔서 감사합니다. 원래 질문에 적용되지 않는 것이 맞지만 올바른 연산자로 업데이트되었습니다.
— David Kaczynski

1
만약 참이 1이고 거짓이 0이라면, +와 *는 정확히 또는 똑같이 행동하고, 2의 보수는 그렇지 않은 것처럼 행동하므로 법은 여전히 ​​적용됩니다.
— a1an

지적 해 주셔서 감사합니다. De Morgan의 법칙이 원래의 질문에 어떻게 적용될 수 있는지 생각하려고했지만 C 프로그래밍이나 이산 수학을 공부 한 지 몇 년이 지났습니다.
— David Kaczynski
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.