泛型编程之乘法

目标

学习泛型编程。了解最古老的算法。从运行结果来看,没有明显变化。乘法已是基本运算,电光火石间就完成了。

泛型编程之乘法泛型乘法验证

奇数odd

公元前两千年的埃及人,已经知道奇数和偶数。它是乘法的关键。在埃及乘法发明之前应该都是累加的。乘以2,加倍的乘法是最好算的。我们把乘数加倍,把被乘数减半,反复这样做,这就是“埃及乘法”,或者叫“俄罗斯农夫算法”。

被乘数和乘数

从叠加变成乘法来看,被乘除就是叠加次数,被叠加的次数。乘数就是被叠加的那个数。之前他们的顺序总容易弄反,或者搞不清。今天是看到出处,原型了。

尾递归函数

文章递归的改造——间隔挑硬币里讲过一些改造递归调用函数的方法。现在讲的乘法是一个更好的例子。尾递归函数是使用与形式参数完全对应的实际参数来进行递归调用,而且只在返回值里进行递归调用。尾递归函数就可以改成迭代的形式。

r + n a r+na r+na

r 是在运算过程中会持续更新的值,用来累计计算好的那部分 n a na na乘积。通过引入变量,得到了尾递归的乘法算法。

def weidigui(r,n,a):
    if odd(n):
        r += a
        if n==1:return r
    n = half(n)
    a += a
    return weidigui(r,n,a)

half(n)是把被乘数减半的方法。

扩展加法链

埃及算法不是总是最好的。当被乘数是15时,可以只加五次就行了。埃及算法的时间复杂度是 log ⁡ 2 15 = 3.9068905956085187 \log_{2}{15}=3.9068905956085187 log215=3.9068905956085187,但是要执行的加法次数是六。

def beichengshu15(a):
    b = (a+a)+a
    c = b+b
    return (c+c)+b

什么东西都可以做得再极致。

代码

def odd(n):
    return n&0x1
def half(n):
    return n>>1
def mult_acc(r,n,a):
    while True:
        if odd(n):
            r += a
            if 1==n:return r
        n = half(n)
        a += a
        
def multiply(n,a):
    while not odd(n):
        a += a
        n = half(n)
    if 1==n:return a
    #even(n-1)-->n-1 != 1
    return mult_acc(a,half(n-1),a+1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值