Каков наилучший способ сделать Java-кодирование для этого типа операций уровня байтов? - PullRequest
3 голосов
/ 02 апреля 2012

Я читаю о некоторых проблемах, связанных с оптимизацией.
В проблеме, как сортировать числа в определенном диапазоне, решение состоит в том, чтобы использовать растровое изображение. И если число может появиться, например, до 10 раз используется для использования полубайтов для отображения чисел и в качестве счетчиков для представления числа вхождений.
Понятие я хорошо понимаю. Моя проблема заключается в том, как реализовать это в Java простым способом.

Я застрял на битовых операциях.
Например, для первой части, чтобы увеличить счетчик на 1, я мог подумать:

Найдите байт
Например. bitValue[i]
Затем выполните byte tmp = bitValue[i] & 0x0F, чтобы получить младшие биты (если счетчик является младшим).
Затем выполните tmp = tmp + 1 для увеличения на 1.
Затем выполните bitValue[i] >> 2, чтобы очистить младшие биты, а затем bitValue[i] <<2, чтобы восстановить. Теперь у нас те же самые старшие биты, что и у исходного, а младшие биты очищены.
Затем выполните bitValue[i] |= tmp, чтобы установить младшие биты.
Теперь bitValue увеличил счетчик младших битов на 1. Верно?

Для старшего бита это будет тот же процесс, но для старших бит.

Тогда, когда я должен проверить, каков номер счетчика.

Я думал использовать битовые маски:
0x0 0x1 0x2 и т. Д. И используйте OR, чтобы проверить номер текущего счетчика.

Все это кажется слишком сложным. Я на правильном пути? Как эти операции лучше всего решаются в Java-кодировании?

Любой вклад, руководство по этому вопросу очень приветствуется.

1 Ответ

3 голосов
/ 02 апреля 2012

Вы определенно на правильном пути. Вот некоторый выделенный код, который увеличивает первые четыре бита или вторые четыре бита int на заданную величину.

Обратите внимание, что здесь я использую int вместо byte. Даже если ваши данные byte, обычно гораздо проще работать с ними как int. Это потому, что битовые операторы Java , такие как | и & и <<, возвращают int. Так что проще всего работать с вашими данными как int, а затем откатиться назад, как только вы сделаете все, что вам нужно.

Кроме того, если вам нужно иметь дело с большим количеством данных (возможно, больше, чем просто два упомянутых вами счетчика) на уровне битов, вы можете рассмотреть BitSet .

public class Test {
    public static void main(String[] args)
    {
        int counter = 0;

        // increment the low bits by 3 and high bits by 2
        counter = addLowBits( counter, 3 );
        counter = addHighBits( counter, 2 );

        // print the hex string to verify
        System.out.println( Integer.toHexString( counter ) );
        System.out.println( "Low Counter: " + ( counter & 0x0F ) );
        System.out.println( "High Counter: " + ( ( counter & 0xF0 ) >> 4 ) );
    }

    public static int addLowBits( int counter, int increment )
    {
        // get the low bits
        int low = counter & 0x0F;

        // increment by 1
        low = low + increment;

        // mask the high bits and insert new low bits
        counter = (counter & 0xF0) | low;

        return counter;
    }

    public static int addHighBits( int counter, int increment )
    {
        // now get high bits
        int high = ( counter & 0xF0 ) >> 4;

        // increment by 1
        high = high + increment;

        // mask the low bits and insert new high bits
        counter = (counter & 0x0F) | ( high << 4 );

        return counter;
    }
}
...