我正在制作一个小型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
怎么了?你能帮帮我吗?
答案 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)
当运算符&,^或|的两个操作数时是类型,可转换(第5.1.8节)到基本整数类型,首先对操作数执行二进制数字提升(第5.6.2节)。
1.如果任何操作数属于引用类型,则进行拆箱转换(第5.1.8节)。
2.广泛的原始转换(第5.1.2节)用于转换以下规则所指定的一个或两个操作数:
如果任一操作数的类型为double,则另一个操作数转换为double。
否则,如果任一操作数的类型为float,则另一个操作数转换为float。
否则,如果任一操作数的类型为long,则另一个操作数转换为long。
- 醇>
否则,两个操作数都将转换为int类型。
因此,下面的表达式首先转换为int
。
arr[i-1]^arr[i];
要将其强制转换为byte
,请使用显式广播:
arr[i] = (byte)(arr[i-1]^arr[i]);