分数(小数)取模 利用逆元 python

本文介绍了如何在Python中利用费马小定理和扩展欧几里得算法解决分数取模问题,如4/3对1000000007取模,得到333333337的结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在腾讯的一次笔试中,要求对分数取模 4/3 对1000000007 取余结果是333333337

1. 利用费马小定理

# 计算 x的y次方 对mod取模
def power(x, y, mod):
    r = 1
    while( y ):
        if y & 1:
            r = (r * x) % mod
        x = (x * x) % mod
        y >>= 1

    return r

x = 3
y = 2
# mod = 100000000 + 7
# 利用费马小定理求与(分母)逆元
mod = 7
inv = power(y, mod - 2, mod)
# 再求x分子乘以逆元取模
ans = x * inv % mod
print(ans )

程序中求的是 二分之三     (3/2)  对 7 的取模结果

 

2. 利用扩展欧几里得算法

 

# 扩展欧几里得算法(求乘法逆元)
def ex_gcd(dividend, divisor):
    if 0 == divisor:
        # 易证明:当除数等于0时,可得 X = 1,
### 逆元计算及其 Python 实现 在密码学和数论领域,逆元是一个重要的概念。对于整数 \(a\) 和正整数 \(m\),如果存在一个整数 \(x\) 使得 \((a \cdot x) \% m = 1\) 成立,则称 \(x\) 是 \(a\) 关于 \(m\) 的乘法逆元。 以下是几种常见的基于 Python 的实现方式: #### 方法一:使用扩展欧几里得算法 扩展欧几里得算法不仅可以用于求两个数的最大公约数(GCD),还可以找到满足线性方程 \(ax + by = GCD(a, b)\) 的系数 \(x\) 和 \(y\)。当 \(GCD(a, m) = 1\) 时,\(x\) 即为 \(a\) \(m\) 的乘法逆元。 下面是具体的实现代码[^4]: ```python def EX_GCD(a, b, arr): if b == 0: arr[0] = 1 arr[1] = 0 return a g = EX_GCD(b, a % b, arr) temp = arr[0] arr[0] = arr[1] arr[1] = temp - int(a / b) * arr[1] return g def ModReverse(a, n): arr = [0, 1] gcd = EX_GCD(a, n, arr) if gcd != 1: return -1 # 如果gcd不等于1,则不存在逆元 else: return (arr[0] % n + n) % n # 返回正值的逆元 # 测试代码 a = 21 b = 25 print(f"{a} {b} 的乘法逆:{ModReverse(a, b)}") ``` 此方法通过递归调用 `EX_GCD` 函数来逐步分解问题并返回结果。注意,只有当 \(GCD(a, m) = 1\) 时才存在乘法逆元。 --- #### 方法二:利用 NumPy 数组简化操作 另一种更简洁的方式是借助 NumPy 库完成类似的逻辑处理[^1]: ```python import numpy as np def euclid(v1: int, v2: int) -> tuple: x = np.array([1, 0, v1]) y = np.array([0, 1, v2]) while True: if y[-1] == 0: return int(x[-1]), np.nan elif y[-1] == 1: return int(y[-1]), int((y[1] + v1) % v1) q = np.floor(x[-1] / y[-1]) t = x - y * q.astype(int) x = y.copy() y = t.copy() # 输入测试 if __name__ == "__main__": result_gcd, inverse_mod = euclid(5, 14) print('最大公约数:%d\t乘法逆元:%d' % (result_gcd, inverse_mod)) ``` 上述代码实现了迭代版本的扩展欧几里得算法,并能够直接输出乘法逆元以及最大公约数。 --- #### 方法三:费马小定理的应用 当数 \(m\) 是素数时,可以通过费马小定理快速求解乘法逆元。具体而言,\((a^{m-2}) \% m\) 就是 \(a\) \(m\) 的乘法逆元。这种方法依赖幂运算函数 `pow(base, exp, mod)` 来高效计算大指数下的结果: ```python def fermat_inverse(a, p): """ 使用费马小定理求 a 关于 p 的乘法逆 """ return pow(a, p - 2, p) # 示例 p = 13 a = 5 inverse = fermat_inverse(a, p) print(f"{a} {p} 的乘法逆:{inverse}") ``` 需要注意的是,该方法仅适用于数为质数的情况。 --- ### 总结 以上三种方法分别展示了不同场景下如何用 Python 计算乘法逆元: 1. 扩展欧几里得算法适合一般情况; 2. 基于 NumPy 的实现提供了一种向量化解决方案; 3. 费马小定理则针对特定条件提供了高效的替代方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值