大数取余方法

在 int32 的存储条件下,大数计算乘法,可能会超出数值范围,导致返回值错误

1. 循环求余法

把指数操作转换成一次次的乘法,每次相乘就取以此余数,使得数值不超过范围

// 求 (x^a) % p —— 循环求余法
public int  remainder(x, a, p){
    int rem = 1;
    while(a--){
        rem = (rem * x) % p;
    }
    return rem;
}
2. 快速幂取余

计算a^n % b,其中a,b和n都是32位的整数。例如 2^31 % 3 = 2,例如 100^1000 % 1000 = 0

用快速幂的方法时间复杂度可以达到O(logn)

快速幂思想:x^2 = x * x;x^4 = x^2 * x2;x8 = x^4 * x^4……

快速幂代码

public static int fastPow(int a, int b) {
    int ans = 1;
    int base = a;
    while(b != 0) {
        if ((b & 1) != 0) {
            ans = ans * base;
        }
        base *= base;
        b >>= 1;
    }
    return ans;
}

然而这里不是简单的快速幂,还要取模.其实也挺简单,先把计算过程中的变量 ans 和 base 的数据类型改成 long ,防止数值越界,然后就是在计算乘法的时候,再加一步取模

public static int fastPow(int a, int b. int n) {
    if (n == 0) { // 规定模 0 是什么
        return 1 % b;
    }
    long ans = 1;
    long base = a;
    while(b != 0) {
        if ((b & 1) != 0) {
            ans = (ans * base) % n;
        }
        base = (base % n) * (base % n);
        b >>= 1;
    }
    return (int)ans;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值