比较C中具有任意位数的两个值

时间:2009-04-10 14:34:02

标签: c casting function-pointers

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

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

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

更新:

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

更新更新:

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

如果我要自己做一个bignum实现,那么ephemient感觉是正确的方法去,但我已经决定我将把这些值记忆到最大可能的类型(即unsigned long long)我将拥有处理并使用这些来处理数学。我想不出有什么理由不起作用,但我认识到我可能会非常错误,因为C /直接记忆操作不是我的强项。

6 个答案:

答案 0 :(得分: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;
    }
}

答案 1 :(得分:1)

也许我也错过了什么......但为什么不使用memcmp?

答案 2 :(得分:1)

如果您正在尝试实施bignum功能(并且您可能会考虑someone else's(首先谷歌点击“C中的bignum”)),您几乎肯定想通过减法来计算差异。大多数CPU通过这样做然后使用结果的符号或者对于&lt;,&gt;或==来实现比较。

答案 3 :(得分:0)

看,我知道,我是一个数学极客,但潜在的问题听起来像“哎呀,这些东西的自然顺序?”

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

答案 4 :(得分:0)

如果只需比较相等 - 请使用memcmp()。如果你需要计算多少位(或字节)不同 - 实现一个类似于memcmp()的函数,它运行在两个char数组中,比较和计算不匹配的模式。

答案 5 :(得分:0)

我认为可变位大小是由于某些值大于其他值。如果可以保证位数始终意味着设置了位数,那么您可以先比较大小,如果大小相等,则进行无符号字节比较。例如,“01”仅需要1比特来存储,因此其大小将为1,并且“100101”需要6比特来存储,因此其大小为6.如果大小(a)>尺寸(b),则(a)> (b)中。

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