6

我正在制作一个加密任何类型文件的小型 Java 程序。我这样做的方式如下:我打开输入文件,在一个与该文件大小相同的字节数组中读取它,然后进行编码,并将整个数组写入一个名为 output 的 .dat 文件。日期。为了索引字节数组,我使用了一个 int 类型的变量。编码:

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

'arr' 是一个与输入文件大小相同的字节数组。

我得到的错误: CodingEvent.java:42: error: possible loss of precision

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

(^ 运算符上的箭头点)

必需:字节

发现:int

怎么了?请问你能帮帮我吗?

4

4 回答 4

7

结果byte ^ byte是,与直觉相反,int。将表达式的结果分配回时使用强制转换arr[i]

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

这是因为运算符被定义为对其操作数进行二进制数字提升,因此它真正在做的(在这种情况下)是:

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

...这自然会导致int. 这就是为什么我们需要演员阵容。

于 2013-07-16T09:34:54.480 回答
1

运算^符的操作数首先转换为一个int(称为二进制数字提升)。所以bytes (arr[i-1]arr[i]) 都被转换为 anint并且运算的结果也是 an int

您需要将结果转换回 abyte以将其分配给arr[i].

于 2013-07-16T09:35:19.700 回答
0

如果 arr[] 是byte[]类型,那么这就是问题所在,当 java 对整数进行任何二进制操作时,它会根据运算符返回intlong 。在这种情况下,arr[i-1]^arr[i]的结果是您尝试将其存储在byte中的int

于 2013-07-16T09:35:25.637 回答
0

看看JLS 15.22.1

当运算符 &、^ 或 | 的两个操作数 是可转换(第 5.1.8 节)为原始整数类型的类型,二进制数字提升首先在操作数上执行(第 5.6.2 节)。

JLS 5.6.2

1.如果任何操作数是引用类型,则对其进行拆箱转换(第 5.1.8 节)。

2. 加宽原语转换(第 5.1.2 节)适用于转换以下规则中指定的一个或两个操作数:

  1. 如果任一操作数是 double 类型,则另一个操作数将转换为 double。

  2. 否则,如果任一操作数的类型为浮点型,则另一个将转换为浮点型。

  3. 否则,如果任一操作数是 long 类型,则另一个将转换为 long。

  4. 否则,两个操作数都转换为 int 类型。

因此,下面的表达式首先转换为int.

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

要将其转换回byte,请使用显式转换:

arr[i] = (byte)(arr[i-1]^arr[i]);
于 2013-07-16T09:39:49.717 回答