//////////////////////////////////////////////////////////////////////////////// #include <iostream> #include <math> //////////////////////////////////////////////////////////////////////////////// void numberQuery(unsigned long long &a, unsigned long long &n, unsigned long long &m); unsigned long long powertworesidual(unsigned long long a, unsigned long long n, unsigned long long m); unsigned long long nonpowertworesidual(unsigned long long a, unsigned long long n, unsigned long long m); //////////////////////////////////////////////////////////////////////////////// int main(void) { unsigned long long a = 0, n = 0, m = 0, buff = 0; for(int i = 0; i < 4; i++) { numberQuery(a, n, m); if(!n) { buff = 1 % m; } else if(n == 2) { buff = (long long)pow(a, n) % m; } else if(!(n & (n - 1))) // If it is a power of 2 number { std::cout << "\nPower entered is a power of 2\n"; buff = powertworesidual(a, n, m); } else // it is not a power of 2 { std::cout << "\nPower entered is not a power of 2\n"; buff = nonpowertworesidual(a, n, m); } std::cout << std::endl << "The residual calculated by the C++" << " modulo operator of " << a << "^" << n << " mod " << m << " is " << ((unsigned long long)pow(a, n) % m); std::cout << std::endl << "The residual calculated by the " << "books algorithm of " << a << "^" << n << " mod " << m << " is " << buff; } } //////////////////////////////////////////////////////////////////////////////// void numberQuery(unsigned long long &a, unsigned long long &n, unsigned long long &m) { std::cout << std::endl << "Please enter a value for \"a\": "; std::cin >> a; std::cout << std::endl << "Please enter a value for \"n\": "; std::cin >> n; std::cout << std::endl << "Please enter a value for the modulus: "; std::cin >> m; while(m == 0) { std::cout << "Cannot divide by zero, please re-enter m\n"; std::cin >> m; } std::cout << "\nYou entered: \na: " << a << "\nn: " << n << "\nmodulus: " << m << std::endl; return; } //////////////////////////////////////////////////////////////////////////////// unsigned long long powertworesidual(unsigned long long a, unsigned long long n, unsigned long long m) { long long residual = 0; /* since it is a power of two, we can safely use two as a constant ** the log2 value is how many times it can be halved, so use a loop ** and multiply by two each time. I am assuming this is what the book ** meant, because the example was short and only showed 4 into 2, 2. */ residual = ((unsigned long long)pow(a, 2) % m); for (int i = 0; i < (log2(n)-1); i++) { residual = ((unsigned long long)pow(residual, 2) % m); } return residual; } //////////////////////////////////////////////////////////////////////////////// unsigned long long nonpowertworesidual(unsigned long long a, unsigned long long n, unsigned long long m) { unsigned long long residual = 1; unsigned long long distance = 0; while(n != 0)// While there are still bits left { if(n & 0x1) // if it is set { /* multiply by a, to the power of 2 to the power of the bits ** position mod m. This is a clever way to avoid conversion */ residual *= ((unsigned long long)pow(a, (unsigned long long)pow(2, distance)) % m); } distance++; // maintain distance n >>= 1; // bitshift right to check next bit } return (residual % m); } ////////////////////////////////////////////////////////////////////////////////