Pregunta

He creado un sistema de tipificación dinámica en C con el fin de crear un diccionario que puede contener valores de diferentes anchos de bit. La estructura del objeto dinámico es:

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

Necesito comparar dos de estas dinámicas que sostienen las lecturas de A2D y luego comparar la diferencia con un valor de Delta para determinar si se ha producido un cambio. Una de las soluciones que han sido capaces de llegar a es para echarlos a char arrays y los compara byte a byte, pero eso no huele bien. También tengo una idea para hacer una matriz de punteros de función en función del número de bytes (o quizás el tipo) la Dinámica tomar y simplemente hacer una función de comparación para cada tipo compatible. ¿Puede alguien sugerir un enfoque diferente? Se siente como que estoy perdiendo algo.

ACTUALIZACIÓN:

Gracias por hablarme de memcmp, pero todavía tengo el problema de cómo consigo el delta de los dos valores? De lo que puedo decir, memcmp sólo devuelve un indicador de qué valor es más grande, no la diferencia entre ellos.

Actualizar para actualizar:

Sus Resulta que memcmp es inútil para mí porque la arquitectura Estoy compilando contra es Little Endian.

Si me iban a hacer una implementación bignum mí mismo entonces ephemient se siente como el camino correcto a seguir, pero he decidido que sólo voy a memcpy los valores en el tipo más grande posible (es decir, unsigned long long) que voy a tener de tratar y trabajar sólo los cálculos usando los. No puedo pensar en ninguna razón por la que esto no iba a funcionar, pero reconozco que podría ser muy malo como C / manipulación directo a memoria no es mi fuerte.

¿Fue útil?

Solución

Es algo como esto suficiente?

#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);
}

La creación de un grupo de funciones especializadas si realizan operaciones muy similares parece un exceso.

Addendum

Si desea calcular las diferencias ...

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;
    }
}

Otros consejos

Tal vez me falta algo también ... pero ¿por qué no usar memcmp?

Si usted está tratando de implementar la funcionalidad bignum (y que podría considerar de otra persona (google por primera vez ha golpeado en 'bignum en C')), que casi con toda seguridad desea calcular la diferencia a través de la resta. La mayoría de las CPU implementan comparan con solo hacer esto y luego usar el signo del resultado o de zeroness <,>, o ==.

Mira, yo soy un friki matemáticas, lo sé, pero la cuestión de fondo suena como "Gee, lo que es el orden natural de estas cosas?"

Es los bits de datos subyacentes primas, como un Bignum? A continuación, las echó en unsigned char y los comparan en un bucle. Un poco de reflexión de la orden en el que se compara hará que sea más eficiente. Un punto interesante es cuando la longitud de A ≠ longitud de B:? Es un ≠ B, entonces, por definición, o es el valor numérico que está comparando, en cuyo caso los principales bytes de 0x00 no son significativas

Si necesita simplemente comparar la igualdad - uso memcmp (). Si tiene que contar el número de bits (o bytes) difieren - implementar una función similar a memcmp () que se ejecuta a través de ambas matrices de carbonilla, comparar y contar los patrones no coincidentes

.

supongo que los tamaños de bits variables se deben a algunos valores que son más grandes que otros. Si usted puede garantizar que el número de bits siempre significa que el número de bit está establecido, entonces primero puede comparar los tamaños y si los tamaños son iguales, y luego hacer las comparaciones de bytes sin signo. Por ejemplo, "01" sólo necesita 1 bit para almacenar, por lo que su tamaño sería 1, y "100.101" requiere 6 bits para almacenar por lo que su tamaño es de 6. Si el tamaño (a)> Tamaño (b), entonces (a)> (b).

Están estos programas almacenados en endian grande o pequeña?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top