取幂的前n位数

时间:2010-10-06 14:04:33

标签: c++ c math exponentiation

如何确定取幂的前n位数( b )。

eg: for a = 12, b = 13 & n = 4, the first 4 digits are 1069.

5 个答案:

答案 0 :(得分:20)

通过以下迭代计算 b

a 1 = a 1
a 2 = a 2
...
a i = a i
...
a b = a b

你有 a i + 1 = a i ×a 。不完全计算每个 a i 。问题是 a b 的相对误差小于 n 乘以 a 的相对误差。
您希望最终相对误差小于 10 -n 。因此,每个步骤的相对误差可能是forumula。删除每一步的最后一位数字。

例如, a = 2 b = 16 n = 1 。最终相对误差 10 -n = 0.1 。每个步骤的相对误差是 0.1 / 16>。 0.001 。因此,每个步骤的3个数字很重要。如果n = 2,则必须保存4位数。通用规则:在每一步保存[ n + log 10 b ]数字。

2(1),4(2),8(3),16(4),32(5),64(6),128(7),256(8),512(9),1024( 10)→102,
204(11),408(12),816(13),1632(14)→163,326(15),652(16)。

答案:6。

此算法具有 O(b)的复杂性。但很容易将其改为 O(log b)

答案 1 :(得分:4)

另一种解决方案,使用log10:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char **argv) {
       int a = 12;
       int b = 13;
       int n = 4;
       double x, y;

       x = b * log10(a);
       y = floor(pow(10, x - floor(x) + n - 1));
       printf("Result: %d\n", (int)y);

       return EXIT_SUCCESS;
}

答案 2 :(得分:3)

n = 9 k = 3 n ^ n = 387420489,答案应为387

enter image description here

这是同样的事情,@ RC和他的代码一样。 谢谢@RC我只是展示了你的代码的数学表示。

答案 3 :(得分:1)

对于这种情况 - 使用幻数12,13,4:

#include <sstream>
#include <iomanip>
#include <cmath>

double a = 12;
int b = 13;
double result = std::pow(a,b);

std::stringstream strVal;
strVal.setf( ios::fixed, ios::floatfield );
strVal << result;
std::string output(strVal.str().substr(0,4));

output =“1069”

std::stringstream intStr(output);
int intVal;
intStr >> intVal;

intVal = 1069

编辑: 这适用于结果不会溢出的任何组合double

答案 4 :(得分:1)

以编程方式执行此操作的最简单方法是使用字符串流将指数结果转换为字符串,然后使用n个最重要(即左)字符。

如果你想要一种没有字符串的方法,那么这将有效:

#include <iostream>
#include <sstream>
#include <math.h>

using namespace std;

double nDigExp( double a, double b, int n )
{
    stringstream ss;
    ss.setf( ios::fixed, ios::floatfield );
    ss << pow(a,b);
    double ret;
    for ( int i = 0; i < n; ++i) ret = (10 * ret) + (ss.get() - '0'); // Yeuch!!
    return ret;
}

int main( )
{
    double result = nDigExp( 12, 13, 4 );

    cout << result << endl;

    return 0;
}

但这不是最优雅的代码。我相信你可以改进它。