C++超大整数位数统计问题:求a^b的位数(1≤a,b≤10^16)
解决超大整数a^b的位数统计问题
嘿,你完全不用折腾自定义超大整数乘法这种笨办法——用数学公式就能在O(1)时间内搞定,绝对符合1秒的时间限制!
核心原理
一个正整数N的位数计算公式是:floor(log10(N)) + 1。对于a^b来说,根据对数的运算法则:log10(a^b) = b * log10(a)
所以a^b的位数就是 floor(b * log10(a)) + 1。
不过要注意两个细节:
- 当
a=1时,不管b多大,结果都是1,位数固定为1(虽然用公式也能算对,但单独处理更直观) - 浮点运算可能存在微小精度误差,比如当
b*log10(a)刚好是整数时,要避免因为精度问题导致floor结果出错
C++实现代码
直接用标准库的对数函数就行,推荐用long double类型来提升计算精度,避免大数值下的精度损失:
#include <iostream> #include <cmath> using namespace std; int main() { unsigned long long a, b; // 因为a,b最大是1e16,用unsigned long long足够存下 cin >> a >> b; if (a == 1) { cout << 1 << endl; return 0; } // 用log10l获取long double精度的对数结果 long double log_result = static_cast<long double>(b) * log10l(static_cast<long double>(a)); int digits = static_cast<int>(floor(log_result)) + 1; // 处理极端情况:当log_result非常接近整数时,修正精度误差 if (fmodl(log_result, 1.0L) < 1e-10L) { digits -= 1; } cout << digits << endl; return 0; }
为什么这个方法高效?
这个方案只需要一次对数运算、一次乘法和少量判断,完全没有循环或复杂运算,哪怕a和b取到最大值1e16,计算也能在瞬间完成,远远低于1秒的时间限制。
举个例子验证:
- 当a=2,b=10时,2^10=1024,位数是4。用公式计算:
10*log10(2)≈3.010,floor后是3,加1得4,完全正确。 - 当a=10,b=5时,10^5=100000,位数是6。公式计算:
5*log10(10)=5,floor后5+1=6,正确。
内容的提问来源于stack exchange,提问作者Justinas Daukša
相关产品推荐
相关产品推荐

