繁体   English   中英

Java错误:可能会损失精度

[英]Java error: possible loss of precision

我正在制作一个小型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];

(^运算符上的箭头点)

必需:字节

发现:int

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

byte ^ byte的结果是反直觉的int 将表达式的结果赋值给arr[i]时,请对表达式的结果使用arr[i]

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

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

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

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

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

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

如果arr []的类型是byte []那么这就是问题,当java用整数执行任何二进制操作时,它会根据运算符返回一个intlong 在这种情况下, 改编的结果[I-1] ^改编[i]是你试图以字节来存储一个int。

看看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. 否则,如果任一操作数的类型为float,则另一个操作数转换为float。

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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