问题
How do i determine the first n digits of an exponentiation (ab).
eg: for a = 12, b = 13 & n = 4, the first 4 digits are 1069.
回答1:
Calculate ab by the following iterations:
a1 = a1,
a2 = a2,
...
ai = ai,
...
ab = ab
You have ai+1 = ai×a. Calcluate each ai not exactly. The thing is that the relative error of ab is less than n times relative error of a.
You want to get final relative error less than 10-n. Thus relative error on each step may be
For example, a=2, b=16, n=1. Final relative error is 10-n = 0.1. Relative error on each step is 0.1/16 > 0.001. Thus 3 digits is important on each step. If n = 2, you must save 4 digits. Common rule: save [n+log10 b] digits at each step.
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).
Answer: 6.
This algorithm has a compexity of O(b). But it is easy to change it to get O(log b)
回答2:
Another solution, using 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;
}
回答3:
n=9 k=3 n^n=387420489 and answer should be 387
this is the same thing, what @RC as done in his code. Thank you @RC i just showed the mathematic representation your code.
回答4:
The easiest way programatically to do this is to use a stringstream to convert the result of the exponentation to a string and then take the n most significant (i.e. left) characters.
if you want a way without strings then this will work:
#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;
}
But it's hardly the most elegent code. I'm sure you can improve it.
回答5:
For this case - with magic numbers 12,13,4 in place:
#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
EDIT:
This should work for any combination where result does not overflow double
.
来源:https://stackoverflow.com/questions/3873298/first-n-digits-of-an-exponentiation