2010-09-01 36 views
56

Tôi không hiểu tại sao giá trị thấp nhất mà một byte có thể thực hiện là -128. Tôi có thể thấy rằng giá trị cao nhất là 127, bởi vì nó là 01111111 trong nhị phân, nhưng làm thế nào để đại diện cho -128 chỉ với 8 bit, một trong số đó được sử dụng cho dấu? Tích cực 128 đã là 8 bit, tức là 10000000 và sau đó bạn sẽ cần bit thứ 9 để biểu thị dấu âm.Tại sao phạm vi byte -128 đến 127 trong Java?

Ai đó có thể vui lòng giúp giải thích điều này với tôi.

+19

[Hai của Complement] (http: //en.wikipedia.org/wiki/Two's_complement) –

+1

Nó tương tự với các kiểu số nguyên khác 'short',' int' và 'long'. – starblue

+6

Một câu hỏi hay hơn là 'tại sao loại byte java không phải là phạm vi 0,2255'? Trong thực tế nhiều người hỏi câu hỏi này, trong hầu hết các ngôn ngữ 'byte' loại là unsigned, nhưng trong java' byte' được ký kết quá, và tôi (và nhiều người khác) tin rằng nó là một thiết kế xấu mà vẫn còn trong Java từ một ngày. Có vấn đề khi bạn đang làm việc JNI, và tin tôi khi bạn đặt tên một cái gì đó 'byte' bạn muốn 0..255! –

Trả lời

63

Câu trả lời là two's complement.

Tóm lại, ngôn ngữ Java (và hầu hết các ngôn ngữ hiện đại) không đại diện cho các số nguyên đã ký bằng cách sử dụng ký hiệu đại diện đã ký. Nói cách khác, một số nguyên 8 bit không phải là một bit dấu, theo sau là một số nguyên không dấu 7 bit. Thay vào đó, số nguyên âm được biểu diễn trong một hệ thống được gọi là bổ sung hai, cho phép xử lý số học dễ dàng hơn trong phần cứng, và cũng loại bỏ sự mơ hồ tiềm ẩn của số không dương và âm. Một tác dụng phụ của việc loại bỏ số không âm là luôn luôn có thêm một số âm có sẵn ở dưới cùng của phạm vi.

Một căn nhà khác thú vị của hệ thống bổ sung hai nhân là bit đầu tiên làm hiệu quả chức năng như một chỉ dấu (tức là tất cả các số bắt đầu với các bit 1 là tiêu cực), nhưng bảy bit tiếp theo là không được giải thích trên của họ sở hữu như một số không dấu mà bit dấu được áp dụng.

Bổ sung của hai không phức tạp khủng khiếp, nhưng nhận được sự hiểu biết ban đầu về bổ sung của hai là gì và tại sao nó hoạt động có lẽ nằm ngoài phạm vi của một câu trả lời SO. Bắt đầu với bài viết trên Wikipedia hoặc google thuật ngữ để biết thêm tài nguyên.

Để cố gắng giải quyết ngắn gọn truy vấn của bạn về -128, ý tưởng cơ bản đằng sau tạo số bổ sung của hai là lấy dạng chưa ký của số, đảo ngược tất cả các bit và thêm một số. Vì vậy, unsigned 128 là 10000000. Đảo ngược, nó là 01111111, và thêm một được 10000000 một lần nữa. Vì vậy, trong một hệ thống bổ sung của hai, 10000000 là unambiguously -128 và không +128. Các số lớn hơn hoặc bằng +128 chỉ đơn giản là không thể được biểu diễn trong 8 bit bằng cách sử dụng hệ thống bổ sung của hai vì chúng sẽ không rõ ràng với các dạng số âm.

+0

Gọn gàng! Hãy xem nếu tôi đã nhận nó ngay mặc dù: nó vẫn đúng là 8-bit số bắt đầu với 0 (khác 00000000) LÀ tích cực, và bắt đầu với 1 là tiêu cực? Ngoài ra, điều thực sự phức tạp duy nhất về sự bổ sung của hai là sự biểu diễn bit của byte không có cùng giá trị mà chúng thực hiện trong một lớp toán, tức là 10000000 là bình thường +128, nhưng như một byte là -128. Amirite? –

+0

Bạn chính xác. Bit đầu tiên là 1 nếu và chỉ khi số đó là số âm. Nếu bit đầu tiên là 0, số đó là số dương hoặc số không. –

+0

@Tyler: Tôi đặt cược bạn có thể trả lời câu hỏi của tôi trong bài đăng này: http://stackoverflow.com/questions/16775169/java-binary-literals-value-128-for-byte Tôi hy vọng đây là không quá thẳng đầu nhưng tôi thực sự tự hỏi và sau một vài tháng tìm kiếm không thường xuyên tôi vẫn không có một đầu mối: ~ – JBA

8

Như James đã chỉ ra trong bình luận của mình, đó là vì đó là cách bổ sung của hai công trình.

Nếu chúng tôi đặt nó theo các thuật ngữ khác, bạn có thể đại diện cho 2^8 = 256 loại giá trị. trong trường hợp này được sử dụng như 128 số âm, 127 số dương và 0. Nếu chúng ta sử dụng 7 bit để biểu thị giá trị, bit +1 cho một dấu, chúng ta có thể biểu diễn một giá trị nhỏ hơn và cũng sẽ có hai số không (sẽ rất không may khi so sánh hai giá trị sẽ phức tạp hơn vì điều đó).

1

trong java tất cả các biến như byte ngắn int long float đôi được viết dưới dạng chữ ký. vì vậy rất đơn giản đầu bit luôn luôn xác định những gì là (tiêu cực hoặc tích cực), nhưng vì các con số có thể chia cho 2 nửa được chuyển thành âm, 0 là dương theo mặc định. để nó trông như thế này:

này là tích cực
+ | 0.001.001
1 | 0.001.001
này là số âm
- | 0.001.001
0 | 0.001.001
như một byte ngắn một tiêu cực là
-000000011111111

3

Số cơ bản ty pes có thể đại diện cho 2^n số. Nhìn vào một trường hợp n = 2. Bạn có thể đại diện cho bốn trường hợp, cho phép gọi chúng là a, b, c, d. Sau đó, bạn có thể đồng ý với a=-2, b=-1, c=0, d=1 (cách này được chấp nhận) hoặc a=-1, b=0, c=1, d=2 (Có thể, nhưng không được sử dụng). Vì vậy, nếu bạn chỉ có một số không và giữ 2^n thì hãy abs(min) != max Tăng số n di chuyển đường viền, nhưng abs(min) != max vẫn giữ.

1

byte gồm 8 bit ---> 1 bit dấu (tích cực hay tiêu cực) giá trị 7 bit

quá phạm vi -2^7 âm (-128) đến 2^7 -1 dương (127)

0

Không tham gia vào phần bổ sung của hai: 2^8 (vì byte là 8 chữ số và có thể có 1 trong 2 giá trị) = 256, do đó, các giá trị riêng lẻ nhất mà byte có thể đại diện là 256. . -128 đến -1 là một nửa phạm vi của chúng tôi. Tôi tin rằng câu hỏi ở đây là lý do tại sao giá trị dương tối đa 127 chứ không phải 128. Điều này là do chúng ta phải đại diện cho số 0, vì vậy toàn bộ 0-127 là 128 khả năng khác trong phạm vi của chúng ta.

Nếu chúng tôi chỉ cho phép các giá trị dương, chẳng hạn như một byte không dấu, nơi số âm không thể, phạm vi sẽ là 0-255, vì đây là 256 giá trị khác nhau (bao gồm 0).

6

Ngoài các câu trả lời ở đây, tôi có thể giải thích cách hoạt động của hai bổ sung.

Một byte bao gồm 8 bit.

00000000 nghĩa 0

11111111 nghĩa là 255

Tuy nhiên, nếu chúng ta chỉ nói như vậy, chúng ta không thể phân biệt được các số dương hoặc âm là. Vì lý do này, bit ở phía bên trái cung cấp cho chúng tôi thông tin này. Nếu bit ở phía bên trái là 0, bạn có thể bắt đầu thêm giá trị của các bit khác trên đầu số không. Nếu bit là 1, bạn nên bắt đầu thêm vào đầu -128. Bởi vì bit ở phía bên trái là hai với sức mạnh của bảy.

Ví dụ;

Trong các ví dụ này, bit ở bên trái là 1, điều đó có nghĩa là chúng tôi đang thêm giá trị của các bit khác lên đầu -128.

10000000 = -128 (-128 + 0)

10000001 = -127 (-128 + 1)

10000011 = -125 (-128 + 3)

10000111 = -121 (-128 + 7)

byte Cùng nhưng lần này, các bit bên trái là 0. Điều đó có nghĩa, chúng tôi đang bắt đầu để thêm trên đỉnh 0.

00000000 = 0 (0 + 0)

00000001 = 1 (0 + 1)

00000011 = 3 (0 + 3)

00000111 = 7 (0 + 7)

Nếu chúng ta là ok đến nay, câu trả lời cho bạn câu hỏi, số nhỏ nhất có thể với 8 bit với quy tắc này là;

10000000 = -128

số lớn nhất có thể

011111111 = 127

Đó là lý do tại sao, phạm vi là giữa -128 và 127.

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