Ошибка 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 (это называется двоичное числовое продвижение). Так как bytes (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).

и 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]);