2013-07-16 11 views
6

Tworzę mały program w języku Java, który szyfruje dowolny typ pliku. Sposób, w jaki to robię, jest następujący: Otwieram plik wejściowy, czytam go w tablicy bajtów o tym samym rozmiarze co ten plik, następnie koduję i zapisuję całą tablicę do pliku .dat o nazwie output. dat. Aby zindeksować tablicę bajtów, używam zmiennej typu int. Kod:Błąd Java: możliwa utrata precyzji

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

'arr' jest tablicą bajtów o tym samym rozmiarze co plik wejściowy.

Błąd uzyskać: CodingEvent.java:42: błąd: możliwość utraty dokładności

ARR [i] = ARR [i-1]^opr [I];

(strzałka plamy na operatora ^)

wymagane: bajt

znaleziono: int

Co się stało? Proszę, mógłbyś mi pomóc?

Odpowiedz

7

Wynik byte^byte jest, wbrew intuicji, int. Użyj obsady na skutek ekspresji podczas przypisywania go do arr[i]:

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

To dlatego, że operator jest zdefiniowany jako robi binary numeric promotion na swoich argumentów, a więc to, co naprawdę robi (w tym przypadku) jest :

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

... co naturalnie skutkuje int. Dlatego potrzebujemy odlewu.

1

Operandy operatorów ^ są najpierw converted to an int (nazywa się to binarną promocją numeryczną). Tak więc zarówno byte s (arr[i-1] i arr[i]) są konwertowane na int, a wynikiem operacji jest również int.

Musisz odrzucić wynik z powrotem do byte, aby przypisać go do arr[i].

+1

LOL! Oboje odnosiliśmy się do binarnej konwersji numerycznej. To po prostu zbyt geekowe. –

0

Jeśli arr [] jest typu byte [] to jest to problem, gdy Java ma żadnej operacji binarnej z liczb całkowitych, to zwraca się więdnąć int lub długiej w zależności od operatorów. W tym przypadku wynik arr [i-1]^arr [i] jest int, który próbujesz zapisać w bajcie.

0

spojrzenie na 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).

I 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.

Stąd poniżej wyrażenie jest przekształcany w int.

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

Aby rzucić go z powrotem do byte użyj wyraźnej Obsada:

arr[i] = (byte)(arr[i-1]^arr[i]); 
Powiązane problemy