zl程序教程

您现在的位置是:首页 >  其他

当前栏目

将参数量化为二进制补码定点数的形式

二进制 参数 形式 量化 补码
2023-09-11 14:20:40 时间

python计算一个小数的补码

这篇博客主要讲如何将小数转换为补码形式


前言

随着人工智能的不断发展,FPGA实现LSTM算法加速成为人工智能的研究热点之一,使用FPGA实现LSTM算法的第一步,就是将LSTM中的矩阵参数变成二进制补码形式,存储到FPGA中,这篇文章主要将如何用python实现求补码操作


一、补码是什么?

关于补码是什么,以及它的作用可以参考这篇博客原码、反码、补码和移码其实很简单

如果首位为符号位,则

4.5的补码为 0100.1

-4.5的补码为1011.1

FPGA中存储参数的格式必须一致,否则需要消耗大量资源去实现不同的解码方式,我们统一将参数n转换为,1位符号位,m位整数位和f位小数位,小数部分截断过小的位数

如果选4位整数(m = 4), 4位小数(f = 4), 首位符号位,则

4.5的补码为 00100 1000

-4.5的补码为11011 1000

当这个数超过m位整数的表示范围时,使用该位数下的最大数来表示它;如果选3位整数(m = 2), 4位小数(f = 4), 首位符号位,则

4.5的补码为 011 1111

-4.5的补码为100 0001

二、代码实现

1.引入库

代码如下:

import torch 
import numpy as np

2.转换正数

代码如下:

def p_d2b(n, m, f): #将一个10进制正数转换为一个2进制数,保留m位整数,f位小数,首位符号位
    b = []
    x = 2
    n = n * np.power(2, f)
    n = int(n)
    while True:
        s = n // x
        y = n % x
        b = b + [y]
        if s == 0:
            break  
        n = s
    b.reverse()
    if(len(b) > (m+f)):
        for i in range(m+f):
            b[i] = 1
            b = b[:m+f]
    elif(len(b) < (m+f)):
        for i in range(m+f-len(b)):
            b.insert(0,0)
    b.insert(0,0)
    a = [str(i) for i in b ]
    return a

3.转换负数

代码如下:

def n_d2b(n, m, f): #求一个10进制负数转换为一个2进制补码形式,保留m位整数,f位小数,首位符号位
    n = -1 * n
    b = p_d2b(n, m, f)
    b[0] = '1'
    flag = 1
    for i in range(len(b)-1,0,-1):
        if b[i]== '1' and flag == 1:
            b[i] = '1'
            flag = 0
        elif b[i] == '0' and flag == 1:
            b[i] = '0'
            flag = 1
        elif b[i] == '0':
            b[i] = '1'
        else:
            b[i] = '0'
    a = [str(i) for i in b ]
    return a

4.任意数求它的补码形式

代码如下:

def d2b(n, m, f): #求一个数n的补码,保留m位整数,n位小数,首位符号位
    if n < 0:
        c = n_d2b(n, m, f)
    else:
        c = p_d2b(n, m, f)
    return c


5.代码验证

求补码运行结果
结果正确

总结

这篇博客用python实现了对一个小数求补码的功能,写的较为复杂,以后再慢慢改吧;