对表示大整数的结构的算术

时间:2015-06-19 02:13:21

标签: c math largenumber integer-arithmetic

我编写了一个Murmur3哈希的实现,并将128位密钥定义为hash128_t

typedef struct
{
    uint64_t p1;
    uint64_t p2;
} hash128_t;

我正在尝试使用这些键编写自己的hashmap,但我不确定如何使用struct或算法来进行算术运算。我需要专门针对模运算的帮助,但是如何将这两个内存块视为一个整数的帮助将非常感激。

我的模数公式是

Dividend - ((Dividend/Divisor) * Divisor)

1 个答案:

答案 0 :(得分:1)

你能做的最简单的事情就是简单地丢弃一半的哈希并在另一半上做模数(简单地使用%)。

下一个最简单的方法是使用现有的bignum库。

但是,如果你想使用整个哈希,你需要在这里进行长时间的划分。实际上有很多方法可以做到这一点;这是一个(完全未经测试的)方法:

uint64_t big_modulo(hash128_t hash, uint64_t divisor) {
    uint64_t accum = hash.p1 % divisor;
    uint64_t shift_buf = hash.p2;

    for (int i = 0; i < 64; i++) {
      accum = accum << 1 | (shift_buf >> 63);
      shift_buf = shift_buf << 1;
      if (accum & (~1LU << 63)) accum = accum % divisor;
    }

    return accum % divisor;
}

请注意,如果除数大于2^63 - 1,这将会中断。修复这个问题留给读者,如果你可以将除数约束到32位空间,那么可以进行各种优化。