booth算法(补码一位乘) python实现

补码一位乘

可能表达不是特别清楚 主要还是看代码吧!(多多指教 谢谢1)

其实就是计算机中的乘法实现:在计算机中  数字是用补码表示的 ,想对于计算机计算较为简单;这里不做介绍

B * C =A  这里B为被乘数,C为乘数

booth:将B表示为补码时符号为用两个1或0表示,将C表示为补码时 符号为用一个0或1表示  如-0.1101*-0.1011  B补码:11.0011 ,-B补码:00.1101 ,其中B补码的前两个1为符号位; -B的补码中前两个0为符号位。  C的补码1.0101中 前一个1位符号位  最后在B的补码后面忝一个0开始计算 。

计算规则:从B补码的倒数第二位开始  这里取i为下标,B[i] ,B[i+1]  若为01则用C+(B补)运算  若为10则用C+(-B补)运算,将计算结果的最后一位作为结果先保存,从结果末尾除去,并在结果前添加0或1(第一位为0加0 否则加1)  将此作为新的C;然后i-1  开始新的运算 直到最后

代码如下:

def getcplmt(st,f=0):#获取补码
    s=st.copy()
    flag=s[0]
    s.reverse()
    i=s.index('1')+1
    if(flag is '-'):
        for t in s[i:]:
            if(t is '1'):
                s[i]='0'
            elif(t is '0'):
                s[i]='1'
            else:
                s[i]=t
            i += 1
        s.reverse()
        s.remove('-')
        s.insert(0,'1')
        if(f!=0):
            s.insert(0, '1')
    else:
        s.reverse()
        s.insert(0,'0')
        if (f != 0):
            s.insert(0, '0')
    return s
def get_x(xt):#-x获取
    x=xt.copy()
    if (x[0] is '-'):
        x.remove('-')
        return getcplmt(x,1)
    else:
        x.insert(0, '-')
        return getcplmt(x,1)
def format(st):#先格式化数据,除去前面的零  方便代码实现
    s=st.copy()
    i=0
    if(s[0] is '-'):
        i=1
    if '.'in s:
        while(s[i] is '0'):
            s.remove('0')
    return s
def add(A,B):#二进制相加
    A=A.copy()
    B=B.copy()
    i=len(B)-1
    d = 0  # 进位
    while(i>=0):
        if(A[i] is '0' and B[i] is '0'):
           if(d==0):
                A[i]='0'
           else:
               A[i]='1'
               d=0
        elif(A[i] is '1' and B[i] is '1'):
            if (d == 0):
                A[i] = '0'
            else:
                A[i] = '1'
            d=1
        else:
            if(d==0):
                A[i]='1'
            else:
                A[i]='0'
                d=1
        i-=1
    return A
def coculate(X,_X,Y):#补码一位乘
    B = X.copy()
    _B = _X.copy()
    C = Y.copy()
    if ('.'in X):
        B.remove('.')
        _B.remove('.')
    A = ['0' for i in B]
    if('.'in C):
        C.remove('.')
    C.append('0')
    i=len(C)-2
    Cn=[]
    re=[]

    while(i>=0):
        if(C[i] is '1' and C[i+1] is '0'):
            Cn.append('-')
        elif(C[i] is '0' and C[i+1] is '1'):
            Cn.append('+')
        else:
            Cn.append('0')
        i-=1
    l=len(Cn)-1
    i=0
    for t in Cn:
        if(t is '+'):
            A=add(A,B)
        elif(t is '-'):
            A = add(A,_B)
        if(l!=i):
            re.insert(0,A.pop())
            if (A[0] is '1'):
                A.insert(0,'1')
            else:
                A.insert(0,'0')
        i+=1
    A.extend(re)
    return A
def main():
    xt,yt=input("请输入乘数被乘数 空格隔开").split()
    x=format(list(xt))
    y=format(list(yt))
    X=getcplmt(x,1)
    _X=get_x(x)
    Y=getcplmt(y)
    print("X补:",''.join(X)," -X补:",''.join(_X)," Y补:",''.join(Y))
    re=[]
    xpoint=0;ypoint=0;  #小数点处理
    if ('.' in X):
        xpoint=len(X)-1-X.index('.')
    if('.' in Y):
        ypoint=len(Y)-1-Y.index('.')
    point=xpoint+ypoint
    re=coculate(X,_X,Y)
    if(0!=point):
        re.insert(len(re)-point,'.')
    print("结果:",''.join(re))
if __name__=="__main__":
    main()

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 16位Booth乘法器Verilog的代码如下: module booth_multiplier(input signed [15:0] multiplicand, input signed [15:0] multiplier, output signed [31:0] product); reg signed [15:0] A; reg signed [15:0] S; reg signed [31:0] P; assign product = P; always @(*) begin A = multiplicand; S = -multiplicand; P = 0; for (int i = 0; i < 16; i = i + 1) begin if (multiplier[0] == 1 && P[0] == 0) begin P = P + A; end else if (multiplier[0] == 0 && P[0] == 1) begin P = P + S; end A = A << 1; S = S << 1; multiplier = multiplier >> 1; end end endmodule 这个模块接受两个16位有符号整数作为输入,使用Booth算法计算它们的乘积,并将结果作为一个32位有符号整数输出。Booth算法是一种快速的乘法算法,它利用了二进制补码的特性,可以在较短的时间内完成大数乘法运算。 ### 回答2: 16位booth乘法器verilog可以基于booth算法实现booth算法是一种利用位移操作的乘法算法,它可以将n位数乘以m位数的运算,转换为n+m位数的加法运算,从而提高运算速度。 在verilog中,可以定义输入端口A、B和输出端口P。首先需要将乘数A和被乘数B扩展为32位有符号整数,然后根据booth算法进行运算。 verilog代码如下: module booth_multi(input signed [15:0] A, input signed [15:0] B, output signed [31:0] P); reg signed [31:0] P_reg; reg [4:0] count; always @(A or B) begin count <= 0; P_reg <= {16'b0, A}; repeat(16) begin if ((P_reg[1:0] == 2'b01) || (P_reg[1:0] == 2'b10)) begin P_reg <= P_reg + (B << 1); end else if ((P_reg[1:0] == 2'b11) || (P_reg[1:0] == 2'b00)) begin P_reg <= P_reg - (B << 1); end P_reg[31:17] <= P_reg[30]; P_reg[30] <= P_reg[29]; P_reg[29:0] <= P_reg[28:1]; count <= count + 1; end P <= P_reg; end endmodule 这段代码实现了16位booth乘法器,输入为16位有符号整数A和B,输出为32位有符号整数P。首先,通过repeat语句循环16次,对输入的乘数和被乘数进行位移和加减操作,最终得到32位的结果。同时,根据booth算法的特点,通过移位操作还可以保留16位的结果,再通过输出P_reg实现结果的输出。最后,通过count统计循环次数,有效地进行n+m位数的加法运算。 ### 回答3: Booth乘法器是一种用于高速乘法的电路,常用于数字信号处理器、FPGA、ASIC等数字电路设计中。其主要原理是通过改变乘数的每一位,将乘法运算转化成加法运算。而16位Booth乘法器则是指将两个16位的二进制数进行乘法运算。 在Verilog中,可以利用多个模块实现16位Booth乘法器。其中,最主要的是16位二进制乘法器模块,它可以将两个16位的二进制数相乘,并输出一个32位的结果。此外,还需要一个模块对输入的乘数进行扩展,使之成为带符号的二进制数。接着,还需要一个计算器模块,对输入信号进行相加减,从而实现Booth算法中的乘法器。最后,还要一个模块,将输出的32位二进制数进行截取和舍入,得到16位的结果。 以下是一个可能的Verilog代码实现: module booth16x16(input signed [15:0] a,b,CLK,RESET,output reg signed [31:0] pro); reg [15:0] A; reg [15:0] B; wire temp_in; reg [4:0] cnt; reg [32:0] pres; initial begin cnt=0; pres=33'b0; end always @(a,b,RESET) begin if(RESET) begin pres=0; cnt=0; end else if(CLK) begin A=a; B=b; cnt<=cnt+1; if(cnt<=16) begin if(B[0]==1) pres<=pres-(A<<(cnt-1)); else pres<=pres+(A<<(cnt-1)); end temp_in<=B[0]; B<={B[15],B[15:1]}; end end assign pro=pres[31:16]; endmodule 该代码中,输入参数a和b为16位有符号的二进制数,CLK为时钟信号,RESET为复位信号,pro为输出的16位乘积结果。 在always块中,首先检查RESET信号是否为真,若为真则将计数器cnt和结果寄存器pres清零;接着检查CLK信号是否为真,若为真则开始计算。 在计算时,先对输入的乘数进行扩展(由于上述代码输入的已经是有符号的16位二进制数,所以这个过程被省略了),然后根据Booth算法的规则进行乘法运算。在每次计算过程中,将乘数向右移动一位,并通过模拟电路将得到的乘积结果加到结果寄存器中。最后,根据组合逻辑实现,输出结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慌逃

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值