Java错误:可能会损失精度

时间:2013-07-16 09:32:40

标签: java byte bytearray

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

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

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

我得到的错误:CodingEvent.java:42:错误:可能会丢失精度

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

(^运算符上的箭头点)

必需:byte

发现:int

怎么了?你能帮帮我吗?

4 个答案:

答案 0 :(得分:7)

byte ^ byte的结果是反直觉的int。将表达式的结果赋值回arr[i]时,请对表达式的结果使用强制转换:

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

这是因为运算符被定义为在其操作数上执行binary numeric promotion,因此它实际上正在做什么(在这种情况下):

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

...自然导致int。这就是我们需要退回的原因。

答案 1 :(得分:1)

^运算符的操作数首先是converted to an int(它被称为二进制数字提升)。因此,byte s(arr[i-1]arr[i])都会转换为int,操作结果也是int

您需要将结果转发回byte以将其分配给arr[i]

答案 2 :(得分:0)

如果arr []的类型为 byte [] ,那就是问题,当java对整数执行任何二进制操作时,它会返回 int 取决于运营商。在这种情况下, arr [i-1] ^ arr [i] 的结果是 int ,您尝试存储在字节

答案 3 :(得分: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. 否则,如果任一操作数的类型为float,则另一个操作数转换为float。

  4.   
  5. 否则,如果任一操作数的类型为long,则另一个操作数转换为long。

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

  8.   

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

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

要将其强制转换为byte,请使用显式广播:

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