Python

您所在的位置:网站首页 怎么用python计算加法 Python

Python

2024-06-15 05:02| 来源: 网络整理| 查看: 265

我们知道,减法在本质上其实是加法,就是把数字前的负号当成这个数字的组成部分

那么,如何实现真正的高精度加法呢(即需要考虑负数的情况)?

一步一步来吧!

PART1:

    有两个很大的非负整数,大概有10^1000的位数那么大,求和?

    这就是很纯的高精度加法,即不用考虑负数的情况,实现如下:

        输入两个大数字符串(非负数):a = '233333'        b = '654654651561'

        输出加法运算结果y,以大数字符串形式表示。

def str_add(a, b): ta = list(a) #字符串转列表 tb = list(b) ta = [int(i) for i in ta] #列表元素转整型 tb = [int(i) for i in tb] ta = list(reversed(ta)) #列表元素反转,个位放在列表低位 tb = list(reversed(tb)) mlen = max(len(ta), len(tb)) ta += [0]*(mlen-len(ta)) #运算数据对齐 tb += [0]*(mlen-len(tb)) y = [0]*(mlen+1) for i in range(0, mlen): #大数加法算法 y[i] += ta[i] + tb[i] y[i+1] = int(y[i]/10) y[i] %= 10 if y[mlen] == 0: #去掉未进位的和最高位0 y.pop() y = list(reversed(y)) #和反转,最高位放列表低位 y = [str(i) for i in y] #列表元素转换为字符 y = ''.join(y) #结果从列表转为字符串 return y

PART2:

      有两个很大的非负整数,大概有10^1000的位数那么大,被减数有可能小于减数,求差?

      这就是所谓的高精减,这里是很纯的减法,即两个数都是非负

      因为不保证被减数不小于减数,所以需要多进行一步判z的符号的操作,实现如下:

        首先,为方便,定义一个大数的类:

class Number(object): def __init__(self, num, cr): self.num = num # 大数的值,字符串表示 self.cr = cr # 大数的符号,1代表正,-1代表负

        假定输入两个大数字符串(非负数):a = '2000000000122'        b = '122'

        则输出减法运算结果z,以大数的类的形式表示:

def sub(x, y): # 算法中间函数,计算数值之差——参数表示为列表,x一定大于y,大端表示 xnum = [int(i) for i in x] ynum = [int(i) for i in y] xnum = list(reversed(xnum)) # 转小端序,便于处理 ynum = list(reversed(ynum)) ynum += [0] * (len(xnum) - len(ynum)) # 数据对齐 znum = [0]*len(xnum) for i in range(0, len(xnum)): # 减法算法 znum[i] = xnum[i] - ynum[i] if znum[i] < 0: xnum[i+1] -= 1 znum[i] += 10 for i in reversed(znum[1:]): # 去掉结果的高位零 if i == 0: znum.pop() else: break znum = list(reversed(znum)) # 转大端序输出 znum = [str(i) for i in znum] return ''.join(znum) def subtract(x, y): # 算法函数入口,判断差的符号——x为被减数,y为减数,大数的类表示 xnum = list(x.num) ynum = list(y.num) z = Number(0, 1) if len(xnum) < len(ynum): z.cr = -1 z.num = sub(ynum, xnum) elif len(xnum) == len(ynum): for i in range(0, len(xnum)): if xnum[i] < ynum[i]: z.cr = -1 z.num = sub(ynum, xnum) return z z.num = sub(xnum, ynum) else: z.num = sub(xnum, ynum) return z

RART3:

      有两个很大的整数,大概有10^1000的位数那么大,求和?

       这就是我们的目的所在!

       其实就是把以上的做法结合起来,在上面两个算法的基础之上加上对两个加数符号的判断即可。

        真 · 高精度加法的完整算法如下:

import math class Number(object): def __init__(self, num, cr): self.num = num # 大数的值,字符串表示 self.cr = cr # 大数的符号,1代表正,-1代表负 def print_bignum(self): if self.num == '0': print('0') return if self.cr < 0: print('-', self.num) else: print(self.num) def sub(x, y): xnum = [int(i) for i in x] ynum = [int(i) for i in y] xnum = list(reversed(xnum)) ynum = list(reversed(ynum)) ynum += [0] * (len(xnum) - len(ynum)) znum = [0]*len(xnum) for i in range(0, len(xnum)): znum[i] = xnum[i] - ynum[i] if znum[i] < 0: xnum[i+1] -= 1 znum[i] += 10 for i in reversed(znum[1:]): if i == 0: znum.pop() else: break znum = list(reversed(znum)) znum = [str(i) for i in znum] return ''.join(znum) def subtract(x, y, z): xnum = list(x.num) ynum = list(y.num) if len(xnum) < len(ynum): z.cr = -1 z.num = sub(ynum, xnum) elif len(xnum) == len(ynum): for i in range(0, len(xnum)): if xnum[i] < ynum[i]: z.cr = -1 z.num = sub(ynum, xnum) return z z.num = sub(xnum, ynum) else: z.num = sub(xnum, ynum) return z def str_add(a, b): ta = list(a) # 字符串转列表 tb = list(b) ta = [int(i) for i in ta] # 列表元素转整型 tb = [int(i) for i in tb] ta = list(reversed(ta)) # 列表元素反转,个位放在列表低位 tb = list(reversed(tb)) mlen = max(len(ta), len(tb)) ta += [0]*(mlen-len(ta)) # 运算数据对齐 tb += [0]*(mlen-len(tb)) y = [0]*(mlen+1) for i in range(0, mlen): # 大数加法算法 y[i] += ta[i] + tb[i] y[i+1] = int(y[i]/10) y[i] %= 10 if y[mlen] == 0: # 去掉未进位的和最高位0 y.pop() y = list(reversed(y)) # 和反转,最高位放列表低位 y = [str(i) for i in y] # 列表元素转换为字符 y = ''.join(y) # 结果从列表转为字符串 return y def mix_ar(x, y): # 判断两个加数的符号,结合纯加法和纯减法算法进行计算 z = Number(0, 0) if x.cr < 0 and y.cr < 0: z.cr = -1 z.num = str_add(x.num, y.num) elif x.cr < 0 and y.cr > 0: subtract(y ,x, z) elif x.cr > 0 and y.cr < 0: subtract(x, y, z) else: z.cr = 1 z.num = str_add(x.num, y.num) return z a = Number('1000', 1) # 测试用例 b = Number('999', 1) z = mix_ar(a, b) z.print_bignum()



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3