Побитовые операторы на unsigned long? - PullRequest
0 голосов
/ 19 марта 2012

В настоящее время я работаю с хэш-функцией как таковой:

unsigned long hashFunc(const char *str, unsigned int tablesize ) // djb2 hash
{   
    unsigned long hash = 5381;
    int c;
    while (c = *str++)
        hash = ((hash << 5) + hash)+ c; /* hash * 33 + c */

    return (hash & tablesize)-1;
}

Очевидно, что побитовый оператор & не выполняется для некоторых длинных значений и возвращает вместо него максимальное значение long. Например, хэширование слова "забота" с размером таблицы 63 возвращает 0xffffffff.

Разве побитовые операторы не предназначены для длинных целых чисел без знака? Если да, какие еще есть варианты?

Ответы [ 3 ]

3 голосов
/ 19 марта 2012

Вы должны поставить «-1» в скобках:

return (hash & (tablesize - 1));

Это работает только в том случае, если известно, что размер таблицы равен двум.

Если размер таблицы не является степеньюиз двух, то вы должны использовать оператор по модулю "%":

return hash % tablesize;

(в этом случае "-1" не требуется).

0 голосов
/ 19 марта 2012

Я немного его протестировал, и, кажется, все работает нормально. Просто как неудача - значение hash для ("care",63) равно 0x17c9504c0, а когда вы выполняете двоичный файл, а с 0x3f вы получаете равное 0. Вычтите 1 и получите 0xffffffffffffffff.

Проблема в вашем коде, а не в машине:)

0 голосов
/ 19 марта 2012

Два типа - unsigned int и unsigned long могут иметь разные размеры, что может привести к тому, что побитовая операция сделает то, что вы не ожидали.Попробуйте сыграть:

return (hash & (unsigned long)tablesize)-1;

(или используйте static_cast, если вы настаиваете)

...