Implement 64-bit modular exponentiation safely
Company: Salesforce
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Overview: This question evaluates proficiency in modular arithmetic, safe 64‑bit integer operations, and algorithmic techniques for overflow‑resistant modular multiplication and exponentiation.
Read the full Salesforce Software Engineer interview experience this question came from
Constraints
- 0 ≤ a < 2^61−1
- 0 ≤ b < 2^61−1
- 1 ≤ m < 2^61−1
- Use only 64-bit operations (or a 128-bit-emulated multiply); no intermediate value may overflow a 64-bit integer in C++/Java
- 0^0 is defined as 1
Examples
Input: (2, 10, 1000)
Expected Output: 24
Explanation: 2^10 = 1024, and 1024 mod 1000 = 24.
Input: (3, 0, 7)
Expected Output: 1
Explanation: Any base to the 0 power is 1, and 1 mod 7 = 1.
Hints
- Square-and-multiply: process the exponent bit by bit. Keep `result` and `base`; whenever the current low bit of the exponent is 1, multiply `result` by `base` (mod m); always square `base` (mod m) and shift the exponent right.
- The dangerous step is the multiply (x*y) % m, not the exponentiation loop. When m is near 2^61, x*y is near 2^122 and overflows 64 bits. Use a 128-bit product (unsigned __int128 in C++) or a binary double-and-add mulmod: result += x then x += x, each reduced mod m, which keeps every value below 2*m < 2^62.
- Handle the corner cases first: if m == 1 the answer is 0; reduce a mod m before the loop; b == 0 must yield 1 (the loop naturally leaves result = 1).