C++中如何计算两个超大十六进制数的模运算?
如何在C++中计算超大十六进制数的模运算
错误原因说明
stoi、stol、stoll这类函数只能处理对应基础数值类型范围内的字符串:
stoi对应int,范围约为±20亿(10位十进制)stoll对应long long,范围约为±9e18(19位十进制)
你的十六进制数转成十进制后有70多位,远超这些类型的存储上限,因此会触发std::out_of_range异常。
方案一:手动实现大数模运算(纯C++无依赖)
我们可以基于模运算的性质 (a * b + c) % m = [(a % m) * (b % m) + c % m] % m,先将十六进制字符串转成十进制字符串,再实现十进制大数的模运算。
代码实现
#include <iostream> #include <string> #include <algorithm> #include <cctype> using namespace std; // 十进制字符串 × 整数 string multiplyString(const string& num, int n) { string result; int carry = 0; for (int i = num.size() - 1; i >= 0; --i) { int product = (num[i] - '0') * n + carry; result.push_back((product % 10) + '0'); carry = product / 10; } while (carry > 0) { result.push_back((carry % 10) + '0'); carry /= 10; } reverse(result.begin(), result.end()); return result; } // 十进制字符串 + 整数 string addString(const string& num, int n) { string result = num; int carry = n; for (int i = result.size() - 1; i >= 0 && carry > 0; --i) { int sum = (result[i] - '0') + carry; result[i] = (sum % 10) + '0'; carry = sum / 10; } while (carry > 0) { result.insert(result.begin(), (carry % 10) + '0'); carry /= 10; } return result; } // 十六进制字符串转十进制字符串 string hexToDecimal(const string& hexStr) { string decimal = "0"; for (char c : hexStr) { int digit = isdigit(c) ? (c - '0') : (toupper(c) - 'A' + 10); decimal = multiplyString(decimal, 16); decimal = addString(decimal, digit); } return decimal; } // 比较两个十进制字符串大小:1=a>b,0=相等,-1=a<b int compareStrings(const string& a, const string& b) { if (a.size() != b.size()) return a.size() > b.size() ? 1 : -1; for (int i = 0; i < a.size(); ++i) { if (a[i] != b[i]) return a[i] > b[i] ? 1 : -1; } return 0; } // 十进制字符串减法(确保a >= b) string subtractString(const string& a, const string& b) { string result; int borrow = 0; for (int i = a.size() - 1, j = b.size() - 1; i >= 0; --i, --j) { int digitA = a[i] - '0' - borrow; int digitB = j >= 0 ? (b[j] - '0') : 0; borrow = 0; if (digitA < digitB) { digitA += 10; borrow = 1; } result.push_back((digitA - digitB) + '0'); } reverse(result.begin(), result.end()); // 去除前导零 size_t startPos = result.find_first_not_of('0'); return startPos != string::npos ? result.substr(startPos) : "0"; } // 十进制字符串模运算 string modString(const string& a, const string& b) { string remainder = "0"; for (char c : a) { remainder = multiplyString(remainder, 10); remainder = addString(remainder, c - '0'); while (compareStrings(remainder, b) >= 0) { remainder = subtractString(remainder, b); } } return remainder; } int main() { string hex_a = "1133A5DCDEF3216A63EB879A82F5A1DC4490CCF6412492CF1B242DB"; string hex_b = "AAB3A5DCDEF3216A6AAA2F5A1DC4490CCF6412492CF1B242DB"; string dec_a = hexToDecimal(hex_a); string dec_b = hexToDecimal(hex_b); string result = modString(dec_a, dec_b); cout << "模运算结果(十进制):" << result << endl; return 0; }
方案二:使用第三方大整数库
如果不想手动实现,可以使用成熟的大整数库简化开发,比如Boost.Multiprecision:
#include <iostream> #include <string> #include <boost/multiprecision/cpp_int.hpp> using namespace std; using namespace boost::multiprecision; int main() { string hex_a = "1133A5DCDEF3216A63EB879A82F5A1DC4490CCF6412492CF1B242DB"; string hex_b = "AAB3A5DCDEF3216A6AAA2F5A1DC4490CCF6412492CF1B242DB"; cpp_int a(hex_a, 16); cpp_int b(hex_b, 16); cpp_int result = a % b; cout << "模运算结果(十进制):" << result << endl; cout << "模运算结果(十六进制):" << hex << result << endl; return 0; }
注意:使用Boost库需要提前安装并配置编译环境。
内容的提问来源于stack exchange,提问作者A D
相关产品推荐
相关产品推荐

