Побитовая операция в Java или C - PullRequest
0 голосов
/ 05 июля 2018

Я хотел бы радикально улучшить временную производительность операции, которую лучше всего описать как немного мудрую операцию. Ниже приведен конструктор для класса BitFile, который принимает три BitFile в качестве параметров. Какой бы бит ни был согласован, первый и второй параметры (firstContender и secondContender) берутся из firstContender в конструируемую BitFile. Все, с чем они не согласны, взято из supportContender.

data - это поле класса, в котором хранятся результат и основа класса BitFile.

compare(byte,byte) возвращает true, если оба байта идентичны по значению.

add(byte,int) принимает байт, представляющий бит, и индекс в бите для извлечения, используется второе поле класса «index» и увеличивается на add(byte,int), чтобы поместить следующий бит в местоположение.

«BitFile.get (int)» возвращает байт с единичным битом, если он равен единице, BitFile.get (9) возвращает байт со значением 2, если второй бит второго байта является один, иначе 0.

Xor побитовая операция может быстро сказать мне, какие биты отличаются в двух BitFile. Есть ли какой-нибудь быстрый способ использовать результат Xor, где все его нули представлены эквивалентным битом firstContender, а все единицы представлены эквивалентным битом supportContender, что-то вроде три операнда Бит Мудрого оператора?

public BitFile(
BitFile firstContender,BitFile secondContender,BitFile supportContender)
{
    if(firstContender.getLength() != secondContender.getLength())
    {
        throw new IllegalArgumentException(
        "Error.\n"+
        "In BitFile constructor.\n"+
        "Two BitFiles must have identical lengths.");
    }
    BitFile randomSet = supportContender;
    int length = firstContender.getLength();
    data = new byte[length];
    for(int i = 0; i < length*8;i++)
    {
        if(compare(firstContender.get(i),secondContender.get(i)))
        {
            add(firstContender.get(i),i%8);
        }
        else
        {
            add(randomSet.get(i),i%8);
        }
    }
}

1 Ответ

0 голосов
/ 06 июля 2018

Я нашел этот вопрос довольно запутанным, но я думаю, что вы вычисляете, как это:

merge(first, second, support) = if first == second then first else support

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

что-то вроде оператора Bit Wise с тремя операндами?

действительно что-то в этом роде. Но, конечно, нам нужно реализовать это вручную с точки зрения операций, поддерживаемых Java. В побитовой арифметике есть два общих шаблона выбора между двумя источниками на основе третьего:

1) (a & ~m) | (b & m)
2) a ^ ((a ^ b) & m)

которые выбирают для каждого бита бит из a, где m равен нулю, и из b, где m равен единице. Шаблон 1 легче понять, поэтому я буду его использовать, но его легко адаптировать ко второму шаблону.

Как вы и предполагали, маска в этом случае будет first ^ second, поэтому:

for (int i = 0; i < data.length; i++) {
    int m = first.data[i] ^ second.data[i];
    data[i] = (byte)((first.data[i] & ~m) | (support.data[i] & m));
}

То же самое можно легко сделать с массивом int или long, для которого потребуется меньше операций для обработки того же объема данных.

...