Why are they different
Because C++'s pow
does floating-point rather than integer math.
In exact integer arithmetic, pow(2012, 17)
would be 145,102,735,039,632,235,424,933,403,463,510,202,882,323,568,682,170,580,992. But the standard IEEE 754 double
can only approximate this value as 1.4510273503963223e+56
, or to be ultra-precise, 145,102,735,039,632,225,543,927,922,730,425,249,428,937,718,149,261,819,904, with only the first 16 sig figs correct. Taking this number modulo 3569 gives 1190, as you have seen.
To get the expected result of 915, you need to use integer arithmetic. I don't think the standard C++ library has a function for that, but it's easy to implement one. Here's a recursive version:
int powmod(int base, int exponent, int modulus)
{
if (exponent == 0)
{
return 1;
}
else if (exponent % 2 == 0)
{
int square_root = powmod(base, exponent / 2, modulus);
return square_root * square_root % modulus;
}
else
{
return powmod(base, exponent - 1, modulus) * base % modulus;
}
}
The else if (exponent % 2 == 0)
special-casing of even exponents isn't required, but allows the algorithm to run in logarithmic rather than linear time.