Пожалуйста, не обращайте внимания на мой предыдущий ответ;это абсолютно неправильно.
Я думаю, что проблема здесь в том, что когда вы составляете биты таким образом:
(b[0] << 24) + (b[1] << 16) + (b[2] << 8) + b[3]
Вы не делаете то, что вы думаете, что выделаешь.В частности, предположим, что b[1]
отрицательно (что это такое).Когда Java выполняет битовые сдвиги, она всегда переводит значение в int
перед выполнением сдвига.Это означает, что b[1]
будет выглядеть следующим образом при продвижении по службе:
11111111 11111111 11111111 bbbbbbbb
Здесь первые 1 взяты из представления целых чисел со знаком дополнения до двух, что делает отрицательные числа, представленные множеством ведущихнули.Когда вы сдвигаете это число вверх, вы получите
11111111 bbbbbbbb 00000000 00000000
Если вы затем добавите эти биты к (b[0] << 24)
, который имеет вид
aaaaaaaa 00000000 00000000 00000000
Вы делаете не get
aaaaaaaa bbbbbbbb 00000000 00000000
Из-за первых 1 в представлении.Чтобы это исправить, вам нужно замаскировать биты знака перед выполнением сложения.В частности, если вы измените
b[1] << 16
на
(b[1] << 16) & 0x00FFFFFF
Затем вы замаскируете биты, чтобы получить
00000000 bbbbbbbb 00000000 00000000
Так что теперь, когда вы добавляете два значения,вы получите
aaaaaaaa bbbbbbbb 00000000 00000000
По желанию.
Таким образом, правильное выражение для составления битов формируется с помощью ANDing в соответствующих масках в соответствующие моменты времени:
(b[0] << 24) + ((b[1] << 16) & 0x00FFFFFF) + ((b[2] << 8) & 0x0000FFFF) + (b[3] & 0x000000FF)
IЯ проверил это на моей системе, и, похоже, он работает нормально.
Надеюсь, это поможет!