2010-10-20 31 views
33

Tôi có vòng lặp sau đây:byte vô tận bất ngờ cho vòng lặp

for (byte i = 0 ; i < 128; i++) { 
    System.out.println(i + 1 + " " + name); 
} 

Khi tôi thực hiện programm của tôi nó in tất cả các số từ -128 đến 127 trong một vòng lặp vô hạn. Lý do tại sao điều này xảy ra?

+0

Ý của bạn là 'dường như là vô tận'? – Fermin

+3

@ Suresh S: Bạn đã viết "byte có thể giữ chỉ lên đến 127 bit", mà thực sự là rất nhiều bit cho một byte để có ;-). – sleske

+0

@joey oops !! lấy làm tiếc . –

Trả lời

78

byte là một loại 1-byte, vì thế có thể khác nhau giữa -128 ... 127, vì vậy tình trạng i < 128 luôn là sự thật. Khi bạn thêm 1-127 nó tràn và trở thành -128 và như vậy trong một (vô hạn) loop ...

+6

câu trả lời này có thực sự xứng đáng với 26 phiếu bầu không? –

+5

@piemesons - CÓ! – Mark

+2

@mark tôi không nghĩ vậy. –

19

Sau 127, khi tăng dần, nó sẽ trở thành -128, do đó, điều kiện của bạn sẽ không khớp.

byte: Loại byte dữ liệu là một 8-bit đã ký hai của số nguyên bổ sung. Nó có giá trị tối thiểu là -128 và giá trị tối đa là 127 (bao gồm). Loại dữ liệu byte có thể hữu ích để tiết kiệm bộ nhớ trong mảng lớn, nơi tiết kiệm bộ nhớ thực sự quan trọng. Chúng cũng có thể được sử dụng thay cho số int trong đó giới hạn của chúng giúp làm rõ mã của bạn; thực tế là phạm vi của một biến được giới hạn có thể đóng vai trò như một dạng tài liệu.


Nó sẽ làm việc như thế này:

0, 1, 2, ..., 126, 127, -128, -127, ... 

như 8 bit có thể đại diện cho một số đăng ký để 127.

Xem here cho các kiểu dữ liệu nguyên thủy.


Ảnh nói nhiều hơn những lời alt text

+2

126,127, -128, -127, ... Bạn đã bỏ lỡ một. – Jorn

+0

@ jorn yup:) ... –

11

Bởi vì byte được ký kết trong Java do đó họ sẽ luôn được ít hơn 128.

Tại sao Java đã chọn byte đã ký là một bí ẩn từ độ sâu của thời gian. Tôi chưa bao giờ có thể hiểu tại sao họ lại bị hỏng một kiểu dữ liệu unsigned hoàn toàn tốt :-)

Hãy thử điều này thay vì:

for (byte i = 0 ; i >= 0; ++i) { 

hoặc, tốt hơn được nêu ra:

for (int i = 0 ; i < 128; ++i) { 
+0

lý do duy nhất tôi có thể nghĩ là tính nhất quán, tất cả các loại tích phân khác được ký kết, vì vậy nếu 'byte' bị hủy bỏ, thì nó sẽ là số lẻ. –

+0

Mặc dù Hệ thống Loại phổ biến trong .NET có giới hạn tương tự đối với các loại đã ký, nếu tôi nhớ chính xác. – Joey

+0

là tôi hay là đoạn trích thứ hai của bạn tương đương với nội dung được đăng? – fortran

7

vì khi tôi == 127 và và bạn thực hiện i ++ nó tràn đến -128.

6

byte loại có phạm vi -128..127. Vì vậy, i luôn nhỏ hơn 128.

2

tốt nhất là nếu bạn làm

for (byte i = 0 ; i < Byte.MAX_VALUE; i++) { 
    System.out.println(i + 1 + " " + name); 
} 
+1

Tốt nhất nếu bạn muốn đếm từ 0 đến 126, nghĩa là :-) – paxdiablo

1

này nên làm việc

 for (byte i = 0 ; i<128; ++i) { 
     if(i==-128) 
      break; 
     System.out.println(i + 1 + " " + "name"); 
    } 
+0

-1, vì hai vấn đề: 1: Điều đó sẽ không hoạt động (tràn - đi tới -128 mà không qua 128) 2: Ngay cả khi không có tràn, khối điều kiện 'if (i == 128)' sẽ không bao giờ được thực hiện - nếu có, nó có nghĩa là vòng lặp 'for' có thể được nhập ngay cả khi nó có điều kiện cho mục nhập là sai. –

+0

@jhominal Có nó không làm việc, xin lỗi về điều đó. Câu trả lời ban đầu của tôi là nếu (i == - 128), sau đó sửa nó thành i == 128. Lỗi của tôi. Đã thay đổi nó trở lại. Bây giờ nó sẽ hoạt động. :) –

+1

Tại sao không thay thế vòng lặp 'for' bằng' cho (byte i = 0; i <128 && i! = - 128; ++ i) '? Điều đó sẽ thoát khỏi câu lệnh 'break'. –

3

Được rồi, vì vậy lý do đằng sau này đã được trả lời đã có, nhưng trong trường hợp bạn đã quan tâm đến một số nền tảng:

A bit là đơn vị lưu trữ nhỏ nhất mà máy tính có thể nhận ra (nb không phải là số nhỏ nhất). Một bit là 0 hoặc 1.

A byte là loại dữ liệu 8 bit, có nghĩa là nó bao gồm 8 chuỗi bit như 10101010 hoặc 0001110. Sử dụng tổ hợp đơn giản, chúng tôi biết rằng có sự kết hợp các byte có thể là 2^8 = 256.

Nếu chúng tôi muốn chỉ đại diện cho số dương, chúng tôi có thể thực hiện chuyển đổi thẳng từ cơ sở 2 sang cơ sở 10. Cách hoạt động là, đối với một chuỗi bit b7b6b5b4b3b2b1b0 số thập phân là dec = sum from n=0 to 7 of (bn * 2^n).

Bằng cách chỉ đại diện cho số dương (một số unsigned byte), chúng tôi có thể đại diện cho 256 số có thể trong phạm vi 0 đến 255 bao gồm.

Sự cố xảy ra khi chúng tôi muốn đại diện cho dữ liệu đã ký. Một cách tiếp cận ngây thơ (n.b. này là cho nền, không phải là cách java hiện nó) là để lấy phần lớn nhất bên trái và làm cho nó bit dấu nơi 1 là tiêu cực và 0 là tích cực. Vì vậy, ví dụ: 00010110 sẽ là 2110010110 sẽ là -21.

Có hai vấn đề lớn với hệ thống như vậy. Đầu tiên là 00000000010000000-0, nhưng như mọi người đều biết, không có -0 bằng cách nào đó khác với 0, nhưng hệ thống như vậy cho phép số và 0 ≠ -0. Vấn đề thứ hai là, do đại diện cho hai số không, hệ thống chỉ cho phép đại diện cho các số từ -127 đến 127, một phạm vi chỉ có 254 (2 nhỏ hơn trước).

Một hệ thống tốt hơn nhiều (và hệ thống mà hầu hết hệ thống sử dụng) được gọi là Two's Compliment. Trong hai lời khen, số dương được biểu diễn bằng chuỗi bit bình thường của chúng ở nơi bit ngoài cùng bên trái là 0. Các số âm được biểu diễn bằng bit bên trái nhiều nhất là 1 và sau đó tính toán lời khen của hai cho số đó (từ đâu hệ thống lấy tên của nó)

Mặc dù về mặt toán học, nó là một quá trình phức tạp hơn một chút, bởi vì chúng ta đang xử lý số 2 có một số vết cắt ngắn. Về cơ bản, bạn có thể lấy phiên bản tích cực và (từ phải sang trái) lấy tất cả số 0 cho đến khi bạn nhấn 1. Sao chép những số 0 và một, sau đó lấy NOT của phần còn lại của các bit. Ví dụ: để có được -21, tích cực 2100010110, chúng tôi lấy số 10 và không còn lại để có được 11101010, biểu thị lời khen của hai là -21.

Hai của khen là một hệ thống nhiều khó khăn hơn để nắm bắt, nhưng nó tránh được những vấn đề đã nêu trước đây, và cho một số n-bit có thể đại diện cho tất cả các chữ số -2^(n-1)-2^(n-1)-1 mà cho byte của chúng tôi có nghĩa -128 để 127 (do đó vấn đề trong câu hỏi này)

Một vài lưu ý:
- Đây chỉ là đại diện số nguyên. Biểu diễn số thực là một hệ thống hoàn toàn khác (nếu có yêu cầu, tôi chắc chắn chúng ta có thể tạo một bài CW đại diện số)
- Wikipedia có thêm một số hệ thống đại diện số nếu bạn quan tâm.

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