2012-11-23 27 views
11

Gần đây tôi đã thực hiện một khóa học Java (khóa học kéo dài 1 tuần), và chúng tôi đã trình bày một số toán học nhị phân.Nhà điều hành "~" đơn nhất - Chính xác những gì đang xảy ra ở đây?

này ~ điều hành unary (dấu ngã Tôi nghĩ rằng nó được gọi là?) Đã giải thích cho chúng tôi như sau:

Nó sẽ đảo ngược các mẫu bit biến mỗi "0" thành một "1" và mỗi "1" thành một " 0 ". ví dụ: Có 8 bit đến một byte. Nếu bạn có byte sau: 00000000 giá trị đảo ngược sẽ thay đổi thành 11111111.

Lời giải thích ở trên rõ ràng và súc tích và hoàn toàn hợp lý với tôi. Cho đến khi, đó là, tôi cố gắng thực hiện nó.

Với này:

byte x = 3; 
byte y = 5; 
System.out.println(~x); 
System.out.println(~y); 

Đầu ra là:

-4 
-6 

Tôi rất bối rối về cách điều này xảy ra.

Nếu +3 ở dạng nhị phân là 11, thì nghịch đảo của số này sẽ là 00, điều này rõ ràng không phải là -3.

Nhưng vì có 8 bit trong một byte, thì không nên biểu diễn nhị phân của +3 được viết là 00000011?

Mà sẽ đảo ngược để trở thành 11111100. Chuyển đổi trở lại giá trị thập phân này sẽ là 252. Nếu bạn viết +3 là 011, thì nó thực sự chuyển thành 100, là +4, nhưng sau đó bạn biết đó là một số âm?

Làm thế nào về nếu bạn thử 0011, chuyển đổi thành 1100, nếu bạn sử dụng bit đầu tiên làm dấu, thì nó thực sự trở thành -4.

Ah - vì vậy tại thời điểm này tôi nghĩ rằng tôi đã nhận được một nơi nào đó.

Nhưng sau đó tôi đã nhận giá trị thứ hai của y = 5.

Làm cách nào để viết? Sử dụng cùng một logic, +5 chuyển đổi thành số nhị phân 0101, chuyển đổi thành 1010.

Và bây giờ tôi đang bối rối một cách khủng khiếp. Điều này có vẻ đại diện cho giá trị đã ký là -2 hoặc giá trị không dấu là 10 thập phân? Không ai trong số đó là -6 Tôi đang được in ra.

Một lần nữa, nếu tôi tăng chiều dài lên đến 8 chữ số của một byte, +5 là 00000101, ngược lại sẽ trở thành 11111010. Và tôi thực sự không thể tìm thấy cách để biến điều này thành -6.

Có ai ngoài kia hiểu điều này, vì tôi không biết điều gì đang xảy ra ở đây và càng nhiều số tôi in ra thì tôi càng bối rối.

Google dường như không đưa ra bất cứ điều gì nhiều về điều này - có lẽ nó không thích nhìn vào dấu hiệu điều hành ít .. :-(

+2

Tất cả các loại số nguyên trong Java được * ký *. –

+2

@MarkoTopolnik char là một loại số và không được ký. –

+0

Sau khi tất cả các câu trả lời rất hữu ích liên quan đến nó là bổ sung của 2, tôi tìm thấy video này mà dường như để giải thích nó khá tốt. Cảm ơn tất cả những ai đã trả lời. http://www.youtube.com/watch?v=Hof95YlLQk0&NR=1&feature=endscreen –

Trả lời

4

Từ wikipedia: Trong ký hiệu bổ sung của hai, một số không âm được biểu thị bằng biểu diễn nhị phân thông thường của nó; trong trường hợp này, bit quan trọng nhất là 0. Hoạt động bổ sung của hai là thao tác phủ định, vì vậy các số âm được biểu thị bằng phần bù của giá trị tuyệt đối của hai.
Để có được sự bổ sung của hai số nhị phân, các bit được đảo ngược, hoặc "lật", bằng cách sử dụng thao tác bitwise NOT; giá trị của 1 sau đó được thêm vào giá trị kết quả, bỏ qua tràn xảy ra khi lấy phần bù hai của số 0. http://en.wikipedia.org/wiki/Two%27s_complement

Vì vậy, nếu bạn có 0101 là +5 nghịch đảo là 1010, là -5 .

Bạn không thực sự đọc 010 là 5 mặc dù, nhưng khi bạn nhìn thấy 1 ở đầu, bạn biết rằng để có được số bạn phải đảo ngược các chữ số còn lại để có được số dương bạn muốn phủ nhận. Nếu điều đó hợp lý.

Đó là một khái niệm xa lạ nếu bạn chưa từng làm việc với nó trước đây. Nó chắc chắn không phải là cách mà số thập phân hoạt động, nhưng nó thực sự đơn giản khi bạn thấy điều gì đang xảy ra.

Một giá trị của 8 thập phân được viết như 01.010, mà phủ nhận để 10101. Các chữ số đầu tiên (1) có nghĩa là nó tiêu cực, và sau đó bạn lật phần còn lại trở lại để có được những giá trị số: 1010.

Một điều cần nhớ là bổ sung của Two không giống như hệ thống nhị phân cũ thông thường. Trong nhị phân bình thường giá trị của 10101 (mà trong bổ sung của hai là -8 như trên) là tất nhiên 21. Tôi đoán đây là nơi mà sự nhầm lẫn đến - làm thế nào để bạn biết sự khác biệt bằng cách nhìn vào chúng? Bạn phải biết đại diện nào đã được sử dụng để quyết định giá trị của con số thực sự là gì. Ngoài ra còn có một bổ sung mà hơi khác một chút.

Hướng dẫn tốt về toán học nhị phân, bao gồm phần bổ sung của One và Two được đưa ra ở đây. http://www.math.grin.edu/~rebelsky/Courses/152/97F/Readings/student-binary

+0

Ồ tôi hiểu rồi. Tôi đã cố gắng để đọc chúng giống như số dương, nhưng với 1 ở phía trước. Cảm ơn vì điều đó. Ngoài ra cho các liên kết - họ là rực rỡ. Cuối cùng tôi đã hiểu nó rồi. Tôi nghĩ. :-) –

+0

Tôi muốn thêm rằng, tất cả điều này xảy ra trong các giá trị 32 bit. Vì vậy, khi bạn nói 3, nó đã được thực sự trong nhị phân 00000000000000000000000000000011. Khi bạn đã đảo ngược nó sẽ trở thành 11111111111111111111111111111100 tương đương với -4 trong bổ sung của hai bit 32 bit. –

7

Xem trình diễn này: -

3 -> 0011 
~3 -> 1100 -> -4 (2's complement) 

5 -> 0101 
~5 -> 1010 -> -6 (2's complement) 

Vì số nguyên đã ký được lưu trữ dưới dạng bổ sung của 2, hãy lấy 2's complement của 1100 cung cấp cho bạn 4. Bây giờ, kể từ 1100 là số âm.Vì vậy, kết quả là -4. Tương tự trường hợp với 1010.

1100 
0011 - 1's complement 
0100 - 2's complement - value = 4 (take negative) 
+1

Ngoài ra, lưu ý rằng toán tử bổ sung bitwise thực hiện quảng cáo bằng số đơn. –

+0

2 bổ sung. Hmm. Huấn luyện viên của chúng tôi đã không đề cập đến điều đó chút nào. Tắt Google Tôi đi. Cảm ơn. :-) –

2

Số nguyên đã ký được lưu trữ gần như bằng cách sử dụng twos complement. Điều này có nghĩa là đảo ngược các bit (lấy phần bổ sung của một người) và thêm một. Bằng cách này bạn không có hai biểu diễn của số nguyên không (+0 và -0), và một số hoạt động đã ký trở nên dễ thực hiện hơn trong phần cứng.

2

Java sử dụng số đã ký trong Two's complement. Lý do của bạn sẽ đúng trong C hoặc các ngôn ngữ khác khi sử dụng các loại như "unsigned int" hoặc "unsigned char".

Các vấn đề liên quan