0

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

In other words, given x such as 2 <= x <= 2^64-1, how to obtain the quotient 2^64 / x, using just uint64?

The problem is that I cannot represent 2^64, let alone to divide it so I was hoping there is a trick which would simulate the result.

Ecir Hana
  • 10,864
  • 13
  • 67
  • 117

2 Answers2

2

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

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

First subtract x from (max _value + 1), then divide by x, add 1.

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

Of course division by 0 is a no-no. Code works for x >= 2, but not x == 1 as the quotient is also not representable.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
1

Take ULLONG_MAX / denom, and add 1 if denom is a power of 2. In pseudocode:

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

Alternatively, take ULLONG_MAX / denom for odd denom, and take 2^63 / (denom / 2) for even denom:

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);
}
user2357112
  • 260,549
  • 28
  • 431
  • 505