4 的 5 次方是 1024
3 的 1024 次方,这个数太大了,pow 函数的返回值类型是 double
就连 double 都无法表示 3 的 1024 次方,你强制转换成 long long 就更无法表示了
还有,就算是使用 long double,16 个字节,128 bit,计算出的结果也是不对的#include <stdio.h>
#include <math.h>
int main(void) {
int a = 3, b = 4, c = 5;
long double n = 1000000007.0L;
long double x = powl(a, powl(b, c));
long double z = fmodl(x, n);
printf("sizeof(long double): %lu\n", sizeof(long double));
printf("a^(b^c)%%%Lf: %Lf\n", n, z);
return 0;
}
/*
$ ./main
sizeof(long double): 16
a^(b^c)%1000000007.000000: 650342243.000000
$
*/
输出的结果不对,是因为 3 的 1024 次方 算的不准确#include <stdio.h>
#include <math.h>
int main(void) {
int a = 3, b = 4, c = 5;
//long double n = 1000000007.0L;
long double x = powl(a, powl(b, c));
//long double z = fmodl(x, n);
//printf("sizeof(long double): %lu\n", sizeof(long double));
//printf("a^(b^c)%%%Lf: %Lf\n", n, z);
printf("a^(b^c): %Lf\n", x);
return 0;
}
/*
$ ./main
a^(b^c): 373391848741020043440934059606603790515058800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
$
*/
我用数学的方法算过了,3 的 1024 次方的个位数字是 1,不是 0,不是其他,是 1
3 的 1 次方 的个位数字是 3
3 的 2 次方 的个位数字是 9
3 的 3 次方 的个位数字是 7
3 的 4 次方 的个位数字是 1
3 的 5 次方 的个位数字是 3
。。。
3 9 7 1 一循环
指数 1 对应 3
指数 2 对应 9
指数 3 对应 7
指数 4 对应 1
(n - 1) % 4 就是 3 的 n 次方 的个位数字 的索引,用来索引 3 9 7 1
0 -> 3
1 -> 9
2 -> 7
3 -> 1
(1024 - 1) % 4 = 3
3 -> 1
所以 3 的 1024 次方的个位数字是 1
我用 python 算了一下,居然正确,这是道 python 题吧,^_^
既然 C语言中的 long double 都算不了,怎么办?
我百度找到了个好东西,gnu 的 mpfr 库The Multiple Precision Floating-Point Reliable Library
google 翻译
官方文档:https://www.mpfr.org/mpfr-4.0.1/mpfr.pdf
#include <stdio.h>
#include <mpfr.h>
int main(void) {
mpfr_t n, a, b, c, z;
mpfr_inits2(8192, n, a, b, c, z, NULL);
mpfr_set_str(n, "1000000007", 10, MPFR_RNDD);
mpfr_inp_str(a, stdin, 10, MPFR_RNDD);
mpfr_inp_str(b, stdin, 10, MPFR_RNDD);
mpfr_inp_str(c, stdin, 10, MPFR_RNDD);
mpfr_pow(z, b, c, MPFR_RNDD);
mpfr_pow(z, a, z, MPFR_RNDD);
mpfr_fmod(z, z, n, MPFR_RNDD);
mpfr_printf("%.0Rf\n", z);
mpfr_clears(n, a, b, c, z, NULL);
mpfr_free_cache();
return 0;
}
编译运行$ gcc -g -Wall -o main main.c -lmpfr
$ ./main
3 4 5
763327764
$
python 估计也是使用了类似的库,要我猜的话,很有可能就是 mpfr
|