简体   繁体   中英

Java error: possible loss of precision

I'm making a small Java program which encrypts any type of file. The way I'm doing it, is the following: I open the input file, read it in a byte array with the same size as that file, then do the encoding, and write the whole array to a .dat file called output.dat. To index the byte array, I'm using a variable of type int. The code:

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

'arr' is a byte array with the same size as the input file.

The error I get: CodingEvent.java:42: error: possible loss of precision

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

(an arrow spots on the ^ operator)

required: byte

found: int

What's wrong? Could you help me please?

The result of byte ^ byte is, counter-intuitively, int . Use a cast on the result of the expression when assigning it back to arr[i] :

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

This is because the operator is defined as doing a binary numeric promotion on its operands, and so what it's really doing (in this case) is:

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

...which naturally results in int . Which is why we need the cast back.

The operands of the ^ operators are first converted to an int (it is called binary numeric promotion). So both byte s ( arr[i-1] and arr[i] ) are converted to an int and the result of the operation is an int too.

You need to cast the result back to a byte to assign it to arr[i] .

If arr[] is of type byte[] then that's the problem, when java does any binary operation with integers, it returns wither an int or long depending of the operators. In this case the result of arr[i-1]^arr[i] is an int that you're trying to store in a byte .

Look at the 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).

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

Hence the below expression is first converted to an int .

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

To cast it back to byte , use an explicit cast :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM