我最近遇到过这个问题。我知道天真的方法,即找到一个^ b,然后提取这个数字'k'次的最低有效数字。 我正在寻找更好的方法。 'a'和'b'是整数。
答案 0 :(得分:3)
a^p < 10^k
时,天真的方法会中断,但a^(p+1)
会溢出。只需要2*10^k-2
来适应变量的解决方案是使用Russian peasant multiplication编写(a*a) mod 10^k
。它通过将a和b除以2的步长来计算a*b
的乘积,因此可以防止溢出,因为您可以在每个步骤之间取模数。
这是函数计算(a * b)%m的c ++实现,没有溢出:
unsigned long long abModm(unsigned long long a, unsigned long long b,unsigned long long m){
unsigned long long res=0;
a=a%m;
b=b%m;
while (b>0){
if (b&1==1){//is b odd
res=(res+a)%m;//collect the result
}
a=(a<<1)%m;//multiply a
b>>=1;//divide b
}
return res;
}
然后您可以使用它来解决其他人已经建议的问题:
int kthDigit(unsigned long long a, unsigned long long b, int k){
unsigned long long m=1;
for (int i=0;i<k;++i) m*=10;
unsigned long long res=1;
for (int i=0;i<b;++i){
res=abModm(res,a,m);
}
m/=10;
return res/m;
}
指数计算是O(b)你可以用O(log(b))和
来做unsigned long long res=1;
while (b){
if (b&1) res=abModm(res,a,m);
b>>=1;
a=abModm(a,a,m);
}
答案 1 :(得分:1)
检查a可被10整除的特殊情况。如果k <1。 b结果为0,如果k≥b则为(a / 10)^ b的(k-b')数字。
计算模10 ^(k + 1)。用模10 ^(k + 1)替换a。对于64位算术,如果k≤18且a <1,则计算很容易。 2 ^ 32。
答案 2 :(得分:1)
通过逐步增加功率,并在每个步骤中丢弃不会影响您正在寻找的数字的最高位数。这将允许您超出实现的整数大小限制。在Javascript中,限制为2 53 -1,您可以计算,例如999999 999999 的第9位数字。
function powerDigit(a, b, k) {
var c = 1, max = Math.pow(10, k);
a %= max;
while (b--) {
c *= a;
// if (c >= Math.pow(2, 53)) return NaN; // Javascript limitation
c %= max;
}
return Math.floor(c * 10 / max);
}
document.write(powerDigit(9, 9, 9) + "<BR>"); // 3 ; 387420489
document.write(powerDigit(99, 9, 9) + "<BR>"); // 4 ; 913517247483640899
document.write(powerDigit(99, 99, 9) + "<BR>"); // 2 ; 3.697296376497267726e+197
document.write(powerDigit(999, 999, 9) + "<BR>"); // 4 ; 3.680634882592232678e+2996
document.write(powerDigit(999999, 999999, 9)); // 9 ; millions of digits
&#13;
答案 3 :(得分:0)
首先你需要找到一个^ b然后你将它除以10 ^(k-1),然后从你得到模数10的结果中得到你的第k个数字。 这里我给出c代码的例子:
double r=pow(a,b)/pow(10,k-1);
int result=(int)r%10;