Написание функции:короткие GetBits (короткие данные, int p, int n)

StackOverflow https://stackoverflow.com/questions/1061528

  •  21-08-2019
  •  | 
  •  

Вопрос

Я пишу функцию short getBits(short data, int p, int n)

Я пытался:

public static short getBits(short data, int p, int n) {
    short bitmask = (short) ((~0 << (16 -n)) >>> p);
    short returnVal = (short) ((bitmask & data) >>> (16 - n));
    return returnVal;
}

Это работает для getBits((short) 0x7000, 0, 4), но если бы я заменил 7 на 8, я получил бы отрицательное значение.

Это было полезно?

Решение

Чтобы все заработало, нужно помнить несколько вещей о типах данных Java.

Я предполагаю, что вы используете переменные типа int из-за отсутствия явного приведения типов в вашем выражении.Если вы используете тип int для своих переменных:данные start_pos и длина;вам следует использовать 32 вместо 16, поскольку int — это 32-битные значения.

Кроме того, если вы собираетесь использовать целочисленные примитивные типы, такие как int, short или byte, помните, что эти примитивные типы представляют собой дополнение до двух и расширены знаком, а это означает, что если вы сделаете сдвиг вправо для отрицательных чисел, таких как ~0 (оценивается как - 1), к старшему биту (знаковому биту) вместо нулей будут добавлены единицы.

Например:

1111 1111 1111 1111 1111 1111 1111 1000        
>>1
1111 1111 1111 1111 1111 1111 1111 1100 

Теперь возвращаясь к вашей проблеме.Общая идея состоит в том, чтобы иметь возможность сделать:

data & mask

Теперь создание маски для подписанных типов данных немного сложнее.Имеет смысл сгенерировать маску, используя:

(~0 << (32 - length) >> (32 - length - start_pos))

Но это, конечно, не сработает из-за расширения знака.

Я бы предложил вместо использования сдвига вправо >> использовать оператор поворота >>> таким образом, вместо добавления битов более высокого порядка, оператор поворота добавит бит младшего порядка.

Например:

1111 1111 1111 1111 1111 1111 1111 1000        
>>>1
0111 1111 1111 1111 1111 1111 1111 1100 

так...

mask = (~0 << 32-length >>> 32-length-start_pos)

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

(data & (~0 << 32-length >>> 32-length-start_pos)) >>> start_pos

Самая внешняя операция поворота перемещает замаскированные данные в биты младшего порядка.

Другие советы

Не уверен, почему вам нужно использовать short.Вот решение, использующее long.

public static long getBits(long data, int p, int n) {
    assert p >= 0 && p < 64;
    assert n >= 0 && n < 64;
    return (data >> p) & ((1 << n) - 1);
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top