0

Given 1 ≤ N ≤ 1018 and 1 ≤ K ≤ 1018, how do I do the operation N % K2? The K2 (Denominator) goes out of bounds for unsigned long long int when K is near the value 1018, so I cannot store the value K2.

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • 1
    [How to ask a good question](https://stackoverflow.com/help/how-to-ask) & [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) – Trenton McKinney Aug 07 '19 at 16:56

2 Answers2

0

You don't really need a bigint library because

  • if K > 109 then K2 > 1018 > N, hence N % K2 = N. No need to calculate K2
  • if K ⩽ 109 then you can calculate N % (K*K) using the normal uint64_t without overflow

FWIW there's also a 128-bit type in most modern compilers in 64-bit mode. GCC, Clang and ICC call it __int128

See Is there a 128 bit integer in gcc?

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • Well you have to take the exact limit (as in my answer), otherwise you won't get the correct answer in some cases (for ex. if N is 5 × 10^18 and K is 2 × 10^9). – Phil1970 Aug 07 '19 at 17:02
  • @Phil1970 the condition is that N ⩽ 10¹⁸ so what you said never happens – phuclv Aug 08 '19 at 01:34
0

Well if K2 is bigger than N then N % K2 is equal to N.

Example:

253 % 172 = 253 % 289 = 253

Assuming 64-bit unsigned long long, the maximum value that can be squared without overflow is 232 - 1 which is equal to 0xFFFFFFFF (or 4'294'967'295).

Thus you can simply have the following code:

unsigned long long compute(unsigned long long n, unsigned long long k)
{
    if (k > 0xFFFFFFFF)
    {
        // k² is bigger than n (require more than 64 bits), so the modulo is n
        return n;
    }

     return n % (k * k);
}
phuclv
  • 37,963
  • 15
  • 156
  • 475
Phil1970
  • 2,605
  • 2
  • 14
  • 15