0

異なるビット幅の値を含むことができる辞書を作成するために、C で動的型付けシステムを作成しました。動的オブジェクトの構造は次のとおりです。

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

A2D 読み取り値を保持するこれらのダイナミクスのうちの 2 つを比較し、その差をデルタ値と比較して、変化が発生したかどうかを判断する必要があります。私が思いついた解決策の 1 つは、それらを char 配列にキャストし、バイトごとに比較することですが、それは正しくありません。また、Dynamics が占めるバイト数 (またはおそらく型) に基づいて関数ポインターの配列を作成し、サポートされている型ごとに比較関数を作成するというアイデアもあります。誰かが別のアプローチを提案できますか? 何かが足りないような気がします。

アップデート:

memcmp について教えていただきありがとうございます。しかし、2 つの値のデルタを取得するにはどうすればよいかという問題がまだ残っています。私が知る限り、 memcmp はどちらの値が大きいかの指標を返すだけであり、それらの差ではありません。

更新する更新:

私がコンパイルしようとしているアーキテクチャがリトル エンディアンであるため、memcmp は役に立たないことがわかりました。

自分で bignum の実装を行う場合は、ephemient が正しい方法のように感じますが、値を可能な限り最大の型 (つまり、unsigned long long) に memcpy することに決めました。それらを使って計算するだけです。これが機能しない理由は思いつきませんが、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 機能を実装しようとしている場合 (そして、他の誰か("bignum in C" で最初の Google ヒット) を検討するかもしれません) は、ほぼ間違いなく減算によって差を計算したいと考えています。ほとんどの CPU は、これを行うだけで比較を実装し、結果の符号または <、>、または == のゼロネスを使用します。

于 2009-04-10T15:28:34.657 に答える
0

ほら、私は数学オタクですが、根底にある問題は「これらの自然な順序は何ですか?」のように聞こえます。

Bignum のように、基礎となるデータは raw ビットですか? 次に、それらを unsigned char にキャストし、ループで比較します。比較する順序を少し考えると、最も効率的になります。興味深い点は、A の長さ ≠ B の長さ: 定義上、A≠B なのか、それとも比較している数値なのかということです。この場合、0x00 の先頭のバイトは重要ではありませんか?

于 2009-04-10T14:40:49.047 に答える
0

等しいかどうかだけを比較する必要がある場合は、memcmp() を使用してください。異なるビット (またはバイト) の数をカウントする必要がある場合は、両方の char 配列を実行する memcmp() と同様の関数を実装し、一致しないパターンを比較してカウントします。

于 2009-04-10T14:43:46.777 に答える
0

可変ビット サイズは、一部の値が他の値よりも大きいためであると推測します。ビット数が常にビット数が設定されていることを意味することを保証できる場合は、最初にサイズを比較し、サイズが等しい場合は符号なしバイト比較を行うことができます。たとえば、「01」は格納に 1 ビットしか必要ないため、サイズは 1 になり、「100101」は格納に 6 ビットが必要になるため、サイズは 6 になります。サイズ (a) > サイズ (b) の場合、(a) > (b)。

これらはビッグエンディアンまたはリトルエンディアンで保存されていますか?

于 2009-04-10T14:46:35.743 に答える