~ x + ~ y == ~ (x + y) luôn sai?


153

Có mã này luôn luôn đánh giá là sai? Cả hai biến là hai ints đã ký bổ sung.

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

Tôi cảm thấy nên có một số số thỏa mãn các điều kiện. Tôi đã thử kiểm tra các con số giữa -50005000nhưng không bao giờ đạt được sự bình đẳng. Có cách nào để thiết lập một phương trình để tìm các giải pháp cho điều kiện không?

Sẽ trao đổi cái này với cái kia gây ra một lỗi sâu sắc trong chương trình của tôi?


6
Bạn có muốn một bằng chứng hoặc một cái gì đó?
Alvin Wong

26
Xin lưu ý rằng trong các trường hợp tràn số nguyên đã ký, đó là hành vi không xác định về mặt kỹ thuật. Vì vậy, nó có thể trở lại truengay cả khi họ không bao giờ có thể giả định bổ sung nghiêm ngặt hai.
Bí ẩn

1
@AlvinWong có một lời giải thích sẽ rất hay
Steve

1
@Steve: Bạn có thể chứng minh rằng bạn đã thử tất cả các nghi phạm thông thường (-1, 0, 1, 2, v.v.) trong tất cả các kết hợp, cũng như các nỗ lực của bạn để "giải quyết" vấn đề cho kích thước từ nhỏ ( ba bit? bốn bit?). Điều đó chắc chắn sẽ giúp thuyết phục chúng tôi rằng chúng tôi không chỉ giúp ai đó có được thứ mà họ không cố gắng tự kiếm tiền trước. :)
đăng

4
@AlexLockwood Khi lần đầu tiên tôi đăng câu hỏi, tôi giả sử gắn thẻ câu hỏi là "bài tập về nhà" yêu cầu mọi người cung cấp manh mối để giúp tôi giải quyết vấn đề (như mô tả về trạng thái thẻ "bài tập về nhà") và không chỉ đưa ra câu trả lời. Đó là lý do tại sao tôi chỉ đơn giản hỏi câu hỏi của vấn đề :)
Steve

Câu trả lời:


237

Giả sử vì mâu thuẫn rằng tồn tại một số xvà một số y(mod 2 n ) sao cho

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

Bằng hai bổ sung *, chúng tôi biết rằng,

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

Lưu ý kết quả này, chúng tôi có,

      ~(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

Do đó, một mâu thuẫn. Do đó, ~(x+y) != ~x + ~ycho tất cả xy(mod 2 n ).


* Thật thú vị khi lưu ý rằng trên một máy có số học bổ sung của một người, sự bình đẳng thực sự đúng với tất cả xy. Điều này là do dưới sự bổ sung của một người , ~x = -x. Như vậy , ~x + ~y == -x + -y == -(x+y) == ~(x+y).


47
Tất nhiên, C không yêu cầu hành vi này; vì nó không yêu cầu hai đại diện bổ sung.
Billy ONeal

12
Btw, sự bình đẳng là đúng cho bổ sung của một người. Hoạt động KHÔNG thực sự không được xác định cho số nói chung, do đó, việc trộn KHÔNG với kết quả cộng trong các hành vi khác nhau tùy thuộc vào cách biểu diễn của số.
nhahtdh

9
Người ta chỉ có thể đặt lại vấn đề cho các số nguyên không dấu và sau đó bổ sung twos hoàn toàn không phát huy tác dụng.
R .. GitHub DỪNG GIÚP ICE

5
Thậm chí đơn giản hơn, IMHO : ~x == -(x+1), vì vậy ~(x+y) == ~x + ~yngụ -(x+y+1) == -(x+1) + -(y+1)ý-1 == -2
BlueRaja - Danny Pflughoeft

7
@BillyONeal, đừng lo lắng, tôi chỉ nói đùa và tôi đánh giá cao rằng bạn đã đề cập đến nó :). Tôi sẽ mua cho bạn đồ uống vào ngày tôi bắt gặp một cỗ máy thực hiện phép tính số học bổ sung của một người ... âm thanh đó như thế nào? haha
Alex Lockwood

113

Bổ sung của hai

Trên đại đa số các máy tính, nếu xlà một số nguyên, thì -xđược biểu diễn dưới dạng ~x + 1. Tương đương , ~x == -(x + 1). Làm cho sự thay thế này trong phương trình của bạn cho:

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

đó là một mâu thuẫn, vì vậy ~x + ~y == ~(x + y)luôn luôn là sai .


Điều đó nói rằng, các giáo viên sẽ chỉ ra rằng C không yêu cầu hai phần bù, vì vậy chúng ta cũng phải xem xét ...

Bổ sung của một người

Trong bổ sung của một người , -xđược đại diện đơn giản là ~x. Zero là trường hợp đặc biệt, có cả hai biểu diễn all-0 ( +0) và all-1's ( -0), nhưng IIRC, C yêu cầu +0 == -0ngay cả khi chúng có các mẫu bit khác nhau, vì vậy đây không phải là vấn đề. Chỉ cần thay thế ~bằng -.

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

Điều này đúng cho tất cả xy.


13
+1 cho câu trả lời thực sự xem xét cả hai phần bù và phần bù của nhau trên cùng một mặt bằng.
một CVn

13
@ dan04 +0 == -0,. Cuối cùng, một cái gì đó có ý nghĩa trong C. :)
Alex Lockwood

32

Chỉ xem xét các bit ngoài cùng bên phải của cả hai xy(IE nếu. x == 13Mà là 1101ở cơ sở 2, chúng ta sẽ chỉ nhìn vào các bit cuối cùng, một 1Sau đó, có bốn trường hợp có thể):

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:

Tôi sẽ để lại cho bạn vì đây là bài tập về nhà (gợi ý: nó giống như trước với x và y được hoán đổi).

x = 1, y = 1:

Tôi cũng sẽ để cái này cho bạn

Bạn có thể chỉ ra rằng bit ngoài cùng bên phải sẽ luôn khác nhau ở phía bên tay trái và bên phải của phương trình với bất kỳ đầu vào nào có thể, vì vậy bạn đã chứng minh rằng cả hai bên không bằng nhau, vì chúng có ít nhất một bit bị lật từ nhau.


27

Nếu số bit là 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.

Hiện nay,

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

Do đó, chúng sẽ luôn không bằng nhau, với chênh lệch là 1.


4
@nhahtdh và làm thế nào để bạn xác định ~hoạt động trên các số chiều rộng không cố định?
hamstergene

1
Tôi đã đưa ra câu trả lời này với số bit này để dễ tương quan với những gì được dạy trong các lớp học. Lưu ý rằng ~ x phụ thuộc nhiều vào số bit, n, được sử dụng để thể hiện số lượng. Vì vậy, thật hợp lý khi gắn bó với một người, khi cố gắng xác minh điều này bằng thực nghiệm.
Karthik Kumar Viswanathan

1
@hamstergene: Tôi biết rằng số lượng bit là cố định, nhưng quan điểm của tôi là nó không phải là số lượng đó (8, 16, v.v.).
nhahtdh

1
Đó là những giá trị mà thật dễ dàng để viết một chương trình để xác minh câu trả lời. Nó hoạt động với mọi n, miễn là ~ x và ~ y được viết để khớp với cái đã cho.
Karthik Kumar Viswanathan

1
@hamstergene: Tôi không có vấn đề gì với bằng chứng, chỉ là những con số đưa ra hàm ý sai rằng nó chỉ hoạt động cho những trường hợp đó.
nhahtdh

27

Dấu:

x + ~x = -1(mod 2 n )

Giả sử mục tiêu của câu hỏi là kiểm tra toán học của bạn (chứ không phải là kỹ năng đọc thông số kỹ thuật của bạn), điều này sẽ đưa bạn đến câu trả lời.


2
Chỉ trên hai máy bổ sung. (Tiêu chuẩn C không yêu cầu điều đó)
Billy ONeal

12
@Billy: Điều đó giống như nói "chỉ dành cho những người hai vũ trang".
dan04

2
@ dan04: Không, không phải vậy. Tôi rất muốn nói tất cả các cường độ đã ký và các đại diện bổ sung đã biến mất khỏi thế giới. Nhưng tôi sẽ sai khi nói điều đó. Tiêu chuẩn C không cho phép bạn đưa ra giả định đó; do đó tôi sẽ nói rằng mã làm cho giả định đó hầu hết là mã xấu. (Đặc biệt là khi thường có những cách gây rối với các số đã ký tốt hơn so với vặn vẹo bit; và đặc biệt khi các số không dấu có thể là lựa chọn tốt hơn hầu hết mọi lúc)
Billy ONeal

10

Trong phần bổ sung của cả một và hai (và thậm chí trong 42), điều này có thể được chứng minh:

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

Bây giờ hãy để a = yvà chúng tôi có:

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

hoặc là:

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

Do đó, trong hai phần bổ sung đó ~0 = -1, mệnh đề này là sai.

Trong phần bổ sung đó ~0 = 0, mệnh đề này là đúng.


7

Theo cuốn sách của Dennis Ritchie, C không thực hiện bổ sung hai theo mặc định. Do đó, câu hỏi của bạn có thể không phải lúc nào cũng đúng.


5

Để MAX_INTlà int được đại diện bởi 011111...111(tuy nhiên có rất nhiều bit). Sau đó, bạn biết rằng, ~x + x = MAX_INT~y + y = MAX_INT, do đó, bạn sẽ biết chắc chắn rằng sự khác biệt giữa ~x + ~y~(x + y)1.


5

C không yêu cầu bổ sung của hai là những gì được thực hiện. Tuy nhiên, đối với các số nguyên tương tự không dấu được áp dụng. Sự khác biệt sẽ luôn là 1 theo logic này!


3

Tất nhiên, C không yêu cầu hành vi này vì nó không yêu cầu biểu diễn bổ sung của hai. Ví dụ: ~x = (2^n - 1) - x& ~y = (2^n - 1) - ysẽ nhận được kết quả này.


0

Ah, toán học rời rạc cơ bản!

Kiểm tra Luật của De Morgan

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

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

Rất quan trọng đối với bằng chứng Boolean!


Chỉ đơn giản là sai. Trong C + là phép cộng, * nhân và không phải là boolean hoặc hoặc.
nalply

Cảm ơn bạn đã chỉ ra các toán tử không chính xác, nalply. Bây giờ nó đã được cập nhật với các toán tử chính xác, mặc dù bạn đúng ở chỗ nó không áp dụng cho câu hỏi ban đầu.
David Kaczynski

1
Chà, nếu đúng là một và sai là 0, thì + và * hành xử chính xác như hoặc và, hơn nữa, bổ sung của hai hành vi như không, do đó luật áp dụng dù sao.
a1an

Cảm ơn bạn đã chỉ ra rằng, a1an. Tôi đã cố gắng nghĩ làm thế nào Luật của De Morgan vẫn có thể áp dụng cho câu hỏi ban đầu, nhưng đã được vài năm kể từ khi tôi học lập trình C hoặc Toán học rời rạc.
David Kaczynski
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.