分子除法 2^64

Division with numerator 2^64

如何在不使用 unit128 的情况下将常数 2^64(即 ULLONG_MAX + 1)除以大于 2 的 uint64

换句话说,给定x比如2 <= x <= 2^64-1,如何得到商2^64 / x,只用uint64?

问题是我无法表示 2^64,更不用说除法了,所以我希望有一个技巧可以模拟结果。

ULLONG_MAX / denom,如果denom是2的幂,则加1。在伪代码中:

if (denom == 0) {
    throw ZeroDivisionException;
} else if (denom == 1) {
    throw OverflowException;
} else {
    return ULLONG_MAX / denom + (denom & (denom-1) == 0);
}

或者,奇数denomULLONG_MAX / denom,偶数denom2^63 / (denom / 2):

if (denom == 0) {
    throw ZeroDivisionException;
} else if (denom == 1) {
    throw OverflowException;
} else if (denom & 1) {
    return ULLONG_MAX / denom;
} else {
    return (1ULL << 63) / (denom >> 1);
}

How to to divide the constant 2^64 (i.e. ULLONG_MAX + 1) by uint64 larger than 2

a/b --> (a-b)/b + 1

先从(max _value + 1)中减去x,然后除以x,加1。

// C solution:
uint64_t foo(uint64_t x) {
  return (0u - x)/x + 1; // max_value + 1 is 0 and unsigned subtraction wraps around.
}

当然不能除以0。代码适用于 x >= 2,但不适用于 x == 1,因为商也不可表示。