|
发表于 2021-9-17 13:59:51
|
显示全部楼层
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
|
|