Сравните два значения, которые содержат произвольное количество битов в C

StackOverflow https://stackoverflow.com/questions/737808

  •  09-09-2019
  •  | 
  •  

Вопрос

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

typedef struct
{
    void* Pointer;
    unsigned char Size;   
} Dynamic;

Мне нужно сравнить две из этих динамик, которые содержат показания A2D, а затем сравнить разницу со значением дельты, чтобы определить, произошло ли изменение.Одно из решений, которое я смог придумать, - это преобразовать их в массивы символов и сравнивать их побайт за побайтом, но это нехорошо пахнет.У меня также есть идея создать массив указателей на функции на основе количества байт (или, возможно, типа), которые занимает Динамика, и просто создать функцию сравнения для каждого поддерживаемого типа.Кто-нибудь может предложить другой подход?Такое чувство, что я чего-то не понимаю.

Обновить:

Спасибо, что рассказали мне о memcmp, но у меня все еще есть проблема, как мне получить дельту двух значений?Из того, что я могу сказать, memcmp просто возвращает индикатор того, какое значение больше, а не разницу между ними.

ОБНОВЛЕНИЕ ЗА ОБНОВЛЕНИЕМ:

Оказывается, memcmp бесполезен для меня, потому что архитектура, с которой я компилирую, имеет небольшой конечный код.

Если бы я собирался сам выполнить реализацию bignum, то ephemient кажется правильным решением, но я решил, что просто собираюсь преобразовать значения в максимально возможный тип (т. Е.unsigned long long), с которыми мне придется иметь дело, и просто поработать с математикой, используя их.Я не могу придумать ни одной причины, по которой это не сработало бы, но я признаю, что могу сильно ошибаться, поскольку C / direct манипулирование памятью - не моя сильная сторона.

Это было полезно?

Решение

Достаточно ли чего-то подобного?

#include <string.h>
int compare(Dynamic *a, Dynamic *b) {
    if (a->Size != b->Size) return a->Size - b->Size;
    return memcmp(a->Pointer, b->Pointer, a->Size);
}

Создание набора специализированных функций, если они выполняют очень похожие операции, кажется излишеством.

Добавление

Если вы хотите вычислить различия...

int diff(Dynamic *a, Dynamic *b, Dynamic *d) {
    int i, borrow = 0;
    signed char *ap = a->Pointer, *bp = b->Pointer, *dp = d->Pointer;

    assert(a->Size == b->Size && b->Size == d->Size);

    for (i = 0; i < a->Size; ap++, bp++, dp++, i++) {
        // symmetric difference
        *dp = *ap ^ *bp;

        // arithmetic difference, assuming little-endian
        *dp = borrow += *bp - *ap;
        borrow >>= 8;
    }
}

Другие советы

Может быть , я тоже чего - то не хватает ... но почему бы вам не использовать memcmp ?

Если вы пытаетесь реализовать функциональность bignum (и вы могли бы рассмотреть чей-то еще (первое попадание Google на "bignum в C")), вы почти наверняка захотите вычислить разницу путем вычитания.Большинство процессоров реализуют compare, выполняя именно это, а затем используя знак результата или нулевую величину для <, >, или ==.

Послушайте, я помешан на математике, я знаю, но основная проблема звучит как "боже, что является естественный порядок этих вещей?"

Являются ли базовые данные необработанными битами, как Bignum?Затем приведите их к unsigned char и сравните их в цикле.Небольшое обдумывание порядка, в котором вы проводите сравнение, сделает его наиболее эффективным.Интересным моментом является то, что длина A ≠ длина B:является ли A≠B тогда по определению, или это числовое значение, которое вы сравниваете, и в этом случае начальные байты 0x00 не являются значимыми?

Если вам нужно просто сравнить для равенства - используйте memcmp().Если вам нужно подсчитать, на сколько битов (или байтов) различаются - реализуйте функцию, аналогичную memcmp(), которая работает через оба массива символов, сравнивает и подсчитывает несовпадающие шаблоны.

Я предполагаю, что размеры переменных битов обусловлены тем, что некоторые значения больше других.Если вы можете гарантировать, что количество битов всегда означает, что номер бита установлен, то вы можете сначала сравнить размеры, и если размеры равны, то выполнить сравнение байтов без знака.Например, для хранения "01" требуется только 1 бит, поэтому его размер будет равен 1, а для хранения "100101" требуется 6 бит, поэтому его размер равен 6.Если размер (a) > размер (b), то (a) > (b).

Хранятся ли они в большом или маленьком конце?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top