Получить байт - как это не так? - PullRequest
2 голосов
/ 02 сентября 2011

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

Ограничения к этой проблеме:

должны использовать биты со знаком, и я не могу использовать умножение. Мне нужно знать, что не так с функцией, как показано ниже.

вот функция:

int retrieveByteFromWord(int word, int byte)
{
  return (word >> (byte << 3)) & 0xFF;
} 

например: (3) (2) (1) (0) ------ номер байта Одним словом: 10010011 11001100 00110011 10101000

Я хочу вернуть байт 2 (11001100)

retrieveByteFromWord (word, 2) ---- дает: 11001100

Но в некоторых случаях это неправильно, и это не скажет мне, в каком случае.

Есть идеи?


Вот проблема:

Вы только начали работать в компании, которая внедряет набор процедур для работы со структурой данных, в которой 4 подписанных байта упакованы в 32-разрядный беззнаковый. Байты в слове пронумерованы от 0 (LSB) до 3 (MSB). Вам была назначена задача реализации функции для машины с использованием 2-х арифметических и арифметических сдвигов вправо со следующим прототипом:

typedef unsigned packed_t

int xbyte(packed_t word, int bytenum);

Это предыдущая попытка сотрудников, уволившая его за ошибки:

int xbyte(packed_t word, int bytenum)
{
  return (word >> (bytenum << 3)) & 0xFF;
}

А) что не так с кодом? Б) Напишите правильную реализацию, используя только сдвиги влево и вправо и одно вычитание.

Я сделал B, но все еще не знаю, почему A не так. Это потому, что десятичные числа идут как 12, 15, 19, 55, а затем упаковываются в слова, а потом, когда я их извлекаю, они больше не совпадают? Может быть, поэтому я собираюсь провести некоторые тесты очень быстро ...

Ответы [ 3 ]

3 голосов
/ 02 сентября 2011

Поскольку это домашнее задание, я не дам вам полного ответа, но я укажу вам правильное направление.В вашем заявлении о проблеме сказано, что:

4 со знаком байтов упакованы в 32-битный без знака.

При битовом & 32-битномцелое число со знаком 0xFF, самый старший бит - то есть знак бит - результата всегда равен 0, поэтому исходная функция никогда не возвращает отрицательное значение независимо от ввода.


В качестве примера ...

Когда вы говорите "retrieveByteFromWord (word, 2) ---- дает: 11001100", вы ошибаетесь.

Тип возвращаемого значения 32битовое целое число - не 8-битное целое.Вы не возвращаете 11001100 Вы возвращаете 00000000 00000000 00000000 11001100.

3 голосов
/ 02 сентября 2011

Для работы с числами используйте целочисленные типы со знаком, например int.

. Для работы с битами используйте целочисленные типы без знака, такие как unsigned,Т.е. пусть аргумент word имеет тип unsigned.Это то, для чего предназначены беззнаковые типы.

Чтобы умножить на 8, напишите просто *8 (это не означает, что эта часть кода технически неверна, просто то, что она искусственно придумана и излишне нечитаема).

Еще лучше, создайте самоописываемое имя для этого магического числа 8, например *bitsPerByte (стандартная библиотека называет его CHAR_BIT, что не является самоописанием и не читабельным).

Наконец, на уровне разработки подумайте о разработке своих функций, чтобы код, который использует вашу функцию - каждый вызов - стал понятным и читабельным.Например, int const b = byteAt( 2, x );.Это может предотвратить ошибки, например, путем предотвращения неправильного фактического порядка аргументов, а поскольку разработка для удобства чтения облегчает чтение кода, это сокращает время, затрачиваемое на это.: -)

Приветствия и hth.,

2 голосов
/ 02 сентября 2011

Работает нормально для положительных чисел.Возможно, вы захотите привести word к unsigned, чтобы он работал для целых чисел с набором MSB.

int retrieveByteFromWord(int word, int byte)
{
  return ((unsigned)word >> (byte << 3)) & 0xFF;
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...