~ 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모든 xy(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)

이는 사실 모두 xy.


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

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

32

단지 오른쪽 모두의 비트 고려 x하고 y(IE를합니다. x == 131101기본 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.