Обнаружить символ ascii в одном байте в 32 или 64 битах - PullRequest
0 голосов
/ 23 февраля 2019

Когда я искал код, который быстрее strlen в C (чем тот, который проверяет побайтно), я нашел этот макрос:

#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)

Этот макрос читает 4 байта и возвращает (1)когда он находит хотя бы один байт NUL.В противном случае он возвращает (0).

Интересно, возможно ли использовать ту же технику для поиска любого символа таблицы ascii (я предпочитаю не использовать байтовый цикл).

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

// in this example I wanted to find a '#'

int32_t detectsharp(int32_t c) {
    c = ~(c - 0x24242424) & ~c;
    return ((c - 0x01010101) & ~c & 0x80808080);
}

Но это не работает с 0x22222222 ("""") или с такими вещами, как 0x24212121 ($!!!).

1 Ответ

0 голосов
/ 23 февраля 2019

Он работает для обнаружения любого символа, если вы предварительно записали его в код с помощью int.

#define DETECTCHAR(x,c) (DETECTNULL((x) ^ ((c)*0x01010101l) ))

Умножение распределяет символ в 4 байтах целого, а xor очищает байт, в котором присутствует символ..

...