具有字节数组和8位整数的模数算法:8位=字节%8位

时间:2012-05-03 22:44:51

标签: c algorithm modulo

我需要创建一个用C实现的算法,该算法在任意数量的字节和一个字节之间进行模运算。见:

typedef struct{
    u_int8_t * data;
    u_int16_t length;
}UBigInt;
u_int8_t UBigIntModuloWithUInt8(UBigInt a,u_int8_t b){

}

对于两个a&的权力(b-1)可以使用但是两个非幂的呢?

我意识到一种方法是:a - b *(a / b)

这将需要使用UBigIntDivisionWithUInt8和UBigIntMultiplicationWithUInt8和UBigIntSubtractionWithUBigInt。可能有更有效的方法来做到这一点?

谢谢。

这是我现在的实施:

u_int8_t UBigIntModuloWithUInt8(UBigInt a,u_int8_t b){
    if (!(b & (b - 1)))
        return a.data[a.length - 1] & b - 1; // For powers of two this can be done
    // Wasn't a power of two.
    u_int16_t result = 0; // Prevents overflow in calculations
    for(int x = 0; x < a.length; x++) {
        result *= (256 % b);
        result %= b;
        result += a.data[x] % b;
        result %= b;
    }
    return result;
}

1 个答案:

答案 0 :(得分:4)

您可以使用Horner方法的变体 使用以下公式逐字节处理:
a % b = ((a // 256) % b) * (256 % b) + (a % 256) % b,其中x // y是舍入除法(正常C整数除法)。这将起作用的原因是同余模b是等价关系 有了这个,您可以使用O(length)算法,或O(log(a)) 示例代码段(未经测试,我的C技能生锈):

u_int16_t result = 0; // Just in case, to prevent overflow
for(i = 0, i<a.length; i++) {
    result *= (256 % b);
    result %= b;
    result += (a[i] % b);
    result %= b;
}

一些理由: 因此a = (a // 256) * 256 + (a % 256) a % b = ((a // 256) * 256) % b + ((a % 256) % b)。但是a % 256 = a[n-1]a // 256 = a[0 .. n-2]。以类似于Horner规则的方式反转动作会为您提供所呈现的片段。