2015-09-02 3 views
1

В Java:Hexadecimal: Установите 8-битные байты в Int

У меня есть 32-разрядное число, данное мне в шестнадцатеричной форме. Мне задано определенное количество байтов (0-3, 0 для младшего байта) и сказано, что мне нужно заменить этот байт другим байтом, который также предоставляется мне в шестнадцатеричной форме. Пример: 32-разрядный номер 0xAAA5BBC6, замените байт 1 на 0x17, чтобы получить 0xAAA517C6.

Я не могу использовать любое литье, умножение, сложение, вычитание или условные обозначения. Я не могу написать какие-либо вспомогательные методы или вызвать любой другой метод из этого или другого файла для реализации любого метода. Кроме того, это должно быть написано в одной строке кода.

Я считаю, что я должен использовать маскировку, но я не могу понять, с чего начать. Учитывая количество байтов, как я могу изменить все 8 бит. Легко переключать один или один, но переключать все 8 бит на определенное значение?

+1

Подумайте о том, как вы замаскируете один бит ... затем попытайтесь скрыть 8 последовательных битов таким же образом. – Buddy

+0

Посмотрите на операторы с битрейтом. Используйте их, чтобы переместить маску на место. – Thilo

+0

Просто примечание: путь пронумерованных байтов _not_ universal. Обычно младший байт 32-разрядного номера называется «байт 0», но я видел его другими способами - я видел, что он называется байтом 3, причем байт 0 является 8 разрядами высокого порядка, и я даже сталкиваюсь с людьми, которые назовут его байтом 4. Поэтому, задавая такой вопрос, лучше всего уточнить. Если вы не знаете, то вам нужно попросить человека, который говорит вам сделать это. – ajb

ответ

0

В одной строке, при условии, что байты время отсчитывается от наименьшего смыслового байта:

int updatedValue = originalValue & ~(0xFF << (byteNumber << 3)) | ((((int)newByte) & 0xFF) << (byteNumber << 3)); 

Где:
originalValue является вашим оригинальным 32-разрядное целое число
newByte является байт вы получаете заменить старый байт
byteNumber это число байт (0-3)

что код делает следующее:

  • создать маску для «удаления» старого байта (очистить бит этого байта). Для того, чтобы создать маску:

    • создать маску байта всех битов (все в 1) 0xFF
    • компенсировано эту маску на позицию байта будет «удален», он должен в 8 раз больше байта, который должен быть «удален».Поскольку я не могу умножить (часть ваших ограничений), то я смещаю это число 3 бита влево (что эквивалентно умножению на 8, помните, что смещение бит в одну позицию влево равносильно умножению на 2, поэтому смещение на 3 будет 2 * 2 * 2 = 8) это делается с помощью этой части кода: (byteNumber << 3)
    • «переключить» биты маски с ~, поэтому у меня есть «удалить» байта: ~(0xFF << (byteNumber << 3)) в этот момент вы маскировать бы, скажет FFFF00FF, если вы хотите, чтобы очистить байты # 1
  • выполнить операцию и-побитовую между исходным номером и масками, созданных на первом этапе: ~(0xFF << (byteNumber << 3))

  • создать 32-битное целое число с новым байтом и смещать его биты в положение байта. Опять же, смещение выполняется с помощью (byteNumber << 3), который уже объяснен.
  • выполнить или побитовое операцию с результатом второго шага, чтобы установить биты нового байта (это строка кода, последний шаг)

Теперь, причина, по которой я делает ((int)newByte) & 0xFF) вместо просто ((int)newByte)) или просто newByte, является то, что JVM способствует int оператору byte перед выполнением операции <<, это может привести к нежелательным последствиям, если вашему newByte больше, чем 0x7F (например, значение 0x80 будет лить в int как 0xFFFFFF80 вместо 0x00000080). Выполняя ((int)newByte) & 0xFF) Я делаю рекламную кампанию до int самостоятельно и очищаю нежелательные биты на всякий случай.

+0

Это работало точно @morgano. Мне просто нужно посмотреть на это и попытаться точно понять, что происходит. Это начинает иметь немного больше смысла, особенно когда добавляются комментарии rakeb.void. –

+0

Ответ обновлен, чтобы объяснить, как это работает. – morgano

+0

Я не могу сказать, насколько это помогло мне! Я смог решить следующую проблему за долю времени! «Возвратите nybble из 32-битного числа, указанного в шестнадцатеричном виде, и который nybble« return (num & (0xF << (который << 2))) >> (который << 2); –

0

Как насчет создания метода (или конструктора класса), целью которого является, в частности, проанализировать шестнадцатеричное значение и перевести его на любой требуемый тип данных. Я настоятельно рекомендую вам прочитать о переводе данных или посмотреть видеоролик об этом на YouTube и посмотреть, как он может относиться к вашему делу. Удачи! - Макс

0

Взгляните на следующий пример:

input = AA  A5   BB  C6 (in hex) 
input = 10101010 10100101 10111011 11000110 (in binary) 
mask = FF  FF  00  FF (in hex) 
mask = 11111111 11111111 00000000 11111111 (in binary) 
------------------------------------------------------- 
input = 10101010 10100101 00000000 11000110 (bitwise AND) 
replace = FF  FF  17  FF (in hex) 
replace = 11111111 11111111 00010111 11111111 (in binary) 
------------------------------------------------------- 
input = 10101010 10100101 00010111 11000110 (bitwise OR) 
input = AA  A5   17  C6 (in hex) 

Последняя строка ваш желаемый результат. Как вы можете видеть, есть две побитовые операции, AND and OR. Вам нужно многому научиться, чтобы узнать, как это работает.

+0

Это очень помогает, спасибо за информацию @ rakeb.void. В этом смысле мы только начали работать с этими операторами. Это кажется довольно продвинутым. –

Смежные вопросы