信息安全数学基础实验一.多精度运算-python实现

def firstNotZero(array):
    for i in range(len(array) - 1, -1, -1):
        if array[i] > 0:
            return i + 1
    return 0

def multiPreSqu(base, num):
    if type(num) is str:
        num = num[::-1]
        num = list(map(int, num))
    t = len(num)
    w = [0] * (2 * t)
    for i in range(t):
        uv = w[2 * i] + num[i]**2
        w[2 * i] = uv % base
        carry = uv // base
        for j in range(i + 1, t):
            uv = w[i + j] + 2 * num[j] * num[i] + carry
            w[i + j] = uv % base
            carry = uv // base
        w[i + t] = carry
    return w

def multiPreGreaterEqual(num1, num2):
    if type(num1) is str:
        num1 = list(map(int, num1))
    else:
        num1 = num1[::-1]
        num1 = num1[len(num1) - firstNotZero(num1[::-1]):]
    if type(num2) is str:
        num2 = list(map(int, num2))
    else:
        num2 = num2[::-1]
        num2 = num2[len(num2) - firstNotZero(num2[::-1]):]
    if len(num1) > len(num2):
        return True
    if len(num1) < len(num2):
        return False
    for i in range(len(num1)):
        if num1[i] > num2[i]:
            return True
        if num1[i] < num2[i]:
            return False
    return True

def multiPreAdd(base, num1, num2):
    if type(num1) is str:
        num1 = num1[::-1]
        num1 = list(map(int, num1))
    if type(num2) is str:
        num2 = num2[::-1]
        num2 = list(map(int, num2))
    result = []
    carry = 0
    for i in range(max(len(num1), len(num2))):
        tmp = carry
        if i < len(num1):
            tmp += num1[i]
        if i < len(num2):
            tmp += num2[i]
        carry = tmp // base
        tmp %= base
        result.append(tmp)
    if carry > 0:
        result.append(carry % base)
    return result

def multiPreSub(base, num1, num2):
    if type(num1) is str:
        num1 = num1[::-1]
        num1 = list(map(int, num1))
    if type(num2) is str:
        num2 = num2[::-1]
        num2 = list(map(int, num2))
    result = []
    borrow = 0
    for i in range(len(num1)):
        tmp = num1[i] + borrow
        if(i < len(num2)):
            tmp -= num2[i]
        borrow = -1 if tmp < 0 else 0
        tmp += -1 * borrow * base
        result.append(tmp)
    
    return result

def multiPreMul(base, num1, num2):
    if type(num1) is str:
        num1 = num1[::-1]
        num1 = list(map(int, num1))
    if type(num2) is str:
        num2 = num2[::-1]
        num2 = list(map(int, num2))
    n = len(num1) - 1
    t = len(num2) - 1
    w = [0] * (n + t + 2)
    for i in range(t + 1):
        carry = 0
        for j in range(n + 1):
            uv = w[i + j] + num1[j] * num2[i] + carry
            w[i + j] = uv % base
            carry = uv // base
        w[i + n + 1] = carry
    return w

def multiPreDiv(base, x, y):
    if type(x) is str:
        x = x[::-1]
        x = list(map(int, x))
    if type(y) is str:
        y = y[::-1]
        y = list(map(int, y))
    n = len(x) - 1
    t = len(y) - 1
    q = [0] * (n - t + 1)
    while multiPreGreaterEqual(x, [0] * (n - t) + y):
        q[n - t] += 1
        x = multiPreSub(base, x,  [0] * (n - t) + y)

    for i in range(n, t, -1):
        if x[i] == y[t]:
            q[i - t - 1] = base - 1
        else:
            q[i - t - 1] = (x[i] * base + x[i - 1]) // y[t]
        judge = x[i] * base * base + x[i - 1] * base + x[i - 2]
        while q[i - t - 1] * (y[t] * base + y[t - 1]) > judge:
            q[i - t - 1] -= 1
        judge = multiPreMul(base, [q[i - t - 1]], [0] * (i - t - 1) + y)
        if not multiPreGreaterEqual(x, judge):
            x = multiPreAdd(base, x, [0] * (i - t - 1) + y)
            q[i - t - 1] -= 1
        x = multiPreSub(base, x, judge)
    return q[:firstNotZero(q)], x[:firstNotZero(x)]

注意,传入的可以是正序的字符串和逆序的列表,传出的是逆序的列表

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值