2013-07-16 49 views
6

Tôi đang tạo một chương trình Java nhỏ mã hóa bất kỳ loại tệp nào. Cách tôi đang làm, như sau: Tôi mở tập tin đầu vào, đọc nó trong một mảng byte với kích thước tương tự như tập tin đó, sau đó làm mã hóa, và viết toàn bộ mảng vào một tập tin .dat được gọi là đầu ra. dat. Để lập chỉ mục mảng byte, tôi đang sử dụng một biến kiểu int. Mã:Lỗi Java: có thể mất chính xác

 for(int i : arr) { 
      if(i>0) { 
       arr[i] = arr[i-1]^arr[i]; 
      } 
     } 

'arr' là mảng byte có cùng kích thước với tệp đầu vào.

Các lỗi tôi nhận được: CodingEvent.java:42: Lỗi: có thể mất độ chính xác

arr [i] = arr [i-1]^arr [i];

(một mũi tên đốm trên các nhà điều hành ^)

yêu cầu: byte

tìm thấy: int

Có chuyện gì vậy? Bạn có thể vui lòng giúp tôi không?

Trả lời

7

Kết quả của byte^byte là, phản trực giác, int. Sử dụng một dàn diễn viên vào kết quả của biểu thức khi giao nó lại cho arr[i]:

arr[i] = (byte)(arr[i-1]^arr[i]); 

này là vì các nhà điều hành được định nghĩa là làm một binary numeric promotion vào toán hạng của nó, và vì vậy những gì nó thực sự làm (trong trường hợp này) được :

arr[i] = (int)arr[i-1]^(int)arr[i]; 

... kết quả tự nhiên trong int. Đó là lý do tại sao chúng tôi cần quay trở lại.

1

Toán hạng của các toán tử ^ là lần đầu tiên converted to an int (được gọi là quảng cáo số nhị phân). Vì vậy, cả hai byte s (arr[i-1]arr[i]) được chuyển đổi thành int và kết quả của thao tác cũng là int.

Bạn cần truyền kết quả trở lại số byte để gán kết quả cho số arr[i].

+1

LOL! Cả hai chúng tôi đều đề cập đến chuyển đổi số nhị phân. Đó là quá geeky. –

0

Nếu arr [] là loại byte [] thì đó là vấn đề, khi java hiện bất kỳ hoạt động nhị phân với số nguyên, nó sẽ trả tàn lụi một int hoặc dài phụ thuộc vào các nhà khai thác. Trong trường hợp này, kết quả của arr [i-1]^arr [i]int mà bạn đang cố gắng lưu trữ trong một byte.

0

Nhìn vào JLS 15.22.1

When both operands of an operator &, ^, or | are of a type that is convertible (§5.1.8) to a primitive integral type, binary numeric promotion is first performed on the operands (§5.6.2).

JLS 5.6.2

1.If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).

2.Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:

  1. If either operand is of type double, the other is converted to double.

  2. Otherwise, if either operand is of type float, the other is converted to float.

  3. Otherwise, if either operand is of type long, the other is converted to long.

  4. Otherwise, both operands are converted to type int.

Do đó các biểu hiện dưới đây là lần đầu tiên chuyển đổi thành một int.

arr[i-1]^arr[i]; 

Để đúc nó trở lại byte, sử dụng một diễn viên rõ ràng:

arr[i] = (byte)(arr[i-1]^arr[i]);