为何使用模1000000007仍返回0?自定义幂运算代码疑问
问题分析与解决方案
兄弟,你遇到的问题本质是整数溢出和取模时机错误,咱们一步步拆解来看:
int类型容量不足导致溢出
你用的rst是int类型,通常它的取值范围是-2^31到2^31-1(约-21亿到21亿)。而2^40的值是1099511627776,这已经远远超出了int能承载的最大值。在循环乘法过程中,rst早就因为溢出变成了无效值(比如负数或0),最后再取模自然得到0。哪怕是b≤30的情况,2^30是1073741824,刚好接近int的上限(2^31-1是2147483647),所以勉强能运行,但其实也处在溢出的边缘。取模时机不对
你只在最后输出时才对rst取模1000000007,但中间乘法过程中已经发生了溢出,这时候再取模已经晚了。正确的做法是每次乘法运算后都立即取模,这样能保证rst始终在较小范围内,不会溢出。b=0的处理逻辑位置错误
你把if(b == 0){rst=1;}放在循环里面,但如果b=0,循环根本不会执行,这个判断完全没起到作用。应该把它放在循环之前处理。
修正后的基础循环版本代码
#include <stdio.h> int main(void) { int a, b; // 用long long存储结果,避免中间运算溢出 long long rst = 1; const int MOD = 1000000007; scanf("%d %d", &a, &b); // 先处理b=0的边界情况 if (b == 0) { rst = 1; } else { for (int i = 0; i < b; i++) { // 每次乘法后立即取模,维持数值在合理范围 rst = (rst * a) % MOD; } } printf("%lld\n", rst); return 0; }
进阶:更高效的快速幂实现
如果需要处理更大的b值,快速幂算法的时间复杂度是O(logn),比循环乘法的O(n)更高效,同样不需要用到pow()函数:
#include <stdio.h> int main(void) { int a, b; long long rst = 1; const int MOD = 1000000007; scanf("%d %d", &a, &b); // 快速幂核心逻辑 while (b > 0) { // 如果b是奇数,先乘一次当前的a if (b % 2 == 1) { rst = (rst * a) % MOD; } // a进行平方,b折半 a = (1LL * a * a) % MOD; b /= 2; } printf("%lld\n", rst); return 0; }
内容的提问来源于stack exchange,提问作者CoffeeStudent
相关产品推荐
相关产品推荐

