Вопрос из исходников redis

Тема в разделе "LANGS.C", создана пользователем perez, 7 сен 2020.

Метки:
  1. perez

    perez Member

    Публикаций:
    0
    Регистрация:
    25 апр 2005
    Сообщения:
    502
    Адрес:
    Moscow city
    Доброго времени суток. Необходимо было разобраться в работе geohash в дерисе, ковыряю исходники.
    Там геохеш хранится в 52-битном варианте бинарно. Есть функция для вывода геохеша в текстовом виде (base32), находится в geo.c, выглядит примитивно:
    ======================
    ...
    char *geoalphabet= "0123456789bcdefghjkmnpqrstuvwxyz";
    ...
    int i;
    for (i = 0; i < 11; i++) {
    int idx = (hash.bits >> (52-((i+1)*5))) & 0x1f;
    buf = geoalphabet[idx];
    }
    buf[11] = '\0';
    ======================

    То есть видим, что просто по 5 бит кодируется каждый символ. В чем собственно вопрос.
    Я решил написать функцию обратного преобразования из строки в бинарный формат.
    НО! Обратите внимание, итератор считает до числа 10, внутри цикла прибавляется единица.
    То есть в теле цикла получается:

    hash.bits >> (52-((i+1)*5) ====> hash.bits >> (52-(11*5) ===> 52-55 = -3

    То есть сдвиг на -3. Такого я не встречал, в инете не нашел. Предполагаю, -3 приводится к unsigned int, значение становится огромным и просто на последней итерации получается ВСЕГДА 0.
    Вопрос №1: это так?

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

    hash origin: 3709594522853587
    hash new: 3709594522853584
    0000000000001101001011011101101101000111110010111010000011010011
    0000000000001101001011011101101101000111110010111010000011010000

    Вопрос #2: почему так сделано? Почему идет потеря точности тупо при кодироваии в base32??
    Версия редиса 5, не верится, что тут такая тупая ошибка просто.
     
    Последнее редактирование: 7 сен 2020
  2. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    > Вопрос №1
    Не факт, может зависеть от архитектуры. А вообще, сдвиг на отрицательное число - тут UB попахивает.

    > Вопрос #2
    А, может, просто тупая ошибка? Постить баг в трекер не пробовали?