0

我在 C 中创建了一个动态类型系统,以便创建一个可以包含不同位宽值的字典。动态对象的结构是:

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

我需要比较其中两个保存 A2D 读数的 Dynamics,然后将差异与 delta 值进行比较,以确定是否发生了变化。我能够想出的一种解决方案是将它们转换为 char 数组并逐字节比较它们,但这并不正确。我还有一个想法,即根据 Dynamics 占用的字节数(或者可能是类型)创建一个函数指针数组,并为每种支持的类型创建一个比较函数。任何人都可以提出不同的方法吗?感觉就像我错过了什么。

更新:

感谢您告诉我有关 memcmp 的信息,但我仍然有如何获得这两个值的增量的问题?据我所知,memcmp 只是返回一个指示哪个值更大的指标,而不是它们之间的差异。

更新到更新:

事实证明 memcmp 对我没用,因为我正在编译的架构是小端。

如果我要自己做一个 bignum 实现,那么 ephemient 感觉是正确的方法,但我决定我只是将值 memcpy 到我必须处理的最大可能类型(即 unsigned long long)中并使用它们进行数学运算。我想不出任何为什么这不起作用,但我认识到我可能是非常错误的,因为 C / 直接内存操作不是我的强项。

4

6 回答 6

2

这样的事情就足够了吗?

#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;
    }
}
于 2009-04-10T14:44:44.310 回答
1

也许我也错过了一些东西......但你为什么不使用 memcmp ?

于 2009-04-10T14:45:57.943 回答
1

如果您正在尝试实现 bignum 功能(并且您可能会考虑其他人的(第一次谷歌点击“C 中的 bignum”)),您几乎肯定希望通过减法计算差异。大多数 CPU 仅通过执行此操作来实现比较,然后将结果的符号或零用于 <、> 或 ==。

于 2009-04-10T15:28:34.657 回答
0

听着,我是个数学极客,我知道,但根本问题听起来像是“天啊,这些东西自然顺序是什么?”

底层数据的原始位是否像 Bignum?然后将它们转换为 unsigned char 并在循环中比较它们。稍微考虑一下您比较的顺序将使其最有效。有趣的一点是,当 A 的长度 ≠ B 的长度时:根据定义,A≠B 是 A≠B,还是您要比较的数值,在这种情况下,0x00 的前导字节不重要?

于 2009-04-10T14:40:49.047 回答
0

如果您只需要比较是否相等 - 使用 memcmp()。如果您需要计算有多少位(或字节)不同 - 实现一个类似于 memcmp() 的函数,该函数贯穿两个 char 数组,比较并计算不匹配的模式。

于 2009-04-10T14:43:46.777 回答
0

我认为可变位大小是由于某些值大于其他值。如果您可以保证位数始终意味着设置了位数,那么您可以先比较大小,如果大小相等,则进行无符号字节比较。例如“01”只需要存储1位,所以它的大小为1,而“100101”需要6位存储,所以它的大小是6。如果size(a) > size(b),那么(a) > (b)。

这些是存储在大端还是小端?

于 2009-04-10T14:46:35.743 回答