Ошибка Java: возможная потеря точности
Я делаю небольшую программу Java, которая шифрует любой тип файла. Способ, которым я это делаю, следующий: я открываю входной файл, читаю его в массиве байтов с тем же размером, что и этот файл, затем делаю кодировку и записываю весь массив в a .файл dat называется output.дат. Чтобы индексировать массив байтов, я использую переменную типа 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 ответов
результат byte ^ byte
есть, вопреки интуиции,int
. Используйте приведение к результату выражения при назначении его обратно в 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[] имеет тип байт[] тогда это проблема, когда java выполняет любую двоичную операцию с целыми числами, она возвращает wither int или долго в зависимости от операторов. В этом случае результат arr[i-1]^arr[i] это int что вы пытаетесь сохранить в байт.
посмотреть JLS 15.22.1
когда оба операнда оператора &, ^, или | из тип, который преобразуется (§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]);