如何将浮点数转换为具有一定宽度和精度的定点数。 python中有没有库可以用来做到这一点?

问题描述 投票:0回答:6

我需要一个函数将浮点数转换为以二进制表示的定点数,以便我可以将其放入只能接受定点数的硬件加速器中。例如,当我输入浮点数 5.625 时,数据宽度为 8,精度为 4(尾数为 4 位),它将返回 b'01011010,或 h'5a 或 d'90。 python库中有类似的函数吗?

python math fixed-point
6个回答
4
投票

这与乘以 16 并转换为 int 相同。

>>> int(5.625 * (2 ** 4))
90

16取决于精度的位数,但很容易计算。

如果数字必须包含多个字节(例如 2 或 4),请使用

struct
模块。例如。对于 300.625,有 32 个数据位,其中 8 个是精度:

>>> int(300.625 * (2**8))
76960
>>> struct.pack('I', 76960)  # 'I' is 4-byte unsigned int
b'\xaa,\x01\x00'

2
投票

您可以在Python中使用fxpmath。您可以在以下位置找到相关信息:

https://github.com/francof2a/fxpmath

在您的示例中:

from fxpmath import Fxp

x = Fxp(5.625, signed=False, n_word=8, n_frac=4)
print(x)         # float value
print(x.bin())   # binary representation
print(x.hex())   # hex repr
print(x.val)     # raw val (decimal of binary stored)

输出:

5.625
01011010
0x5a
90


1
投票

一些定点库如numfi可以将浮点数转换为定点并给出bin/dec/hex表示

>>> from numfi import numfi
>>> x = numfi(5.625,1,8,4)
>>> x.int # d'90
array([90], dtype=int64)
>>> x.bin # b'01011010
array(['01011010'], dtype='<U8')
>>> x.hex # h'5a
array(['5A'], dtype='<U2')

如果您喜欢更简单的解决方案,您可以自己进行量化:

num = 5.625
w = 8 # data width
f = 4 # fraction width
quantized = np.round(num*(2**f)).astype(int) #note: overflow is not considered here
dec_repr = np.base_repr(quantized, base=10)
bin_repr = np.binary_repr(quantized, width=8)
hex_repr = np.base_repr(quantized, base=16)

0
投票

尝试使用decimal模块。

您可以向其传递一个具有所需格式和精度的字符串格式的浮点数:

>>> from decimal import Decimal

>>> '{:5f}'.format(10.0)
'10.000000'

>>> Decimal('{:5f}'.format(10.0))
Decimal('10.000000')

0
投票
def float2fix(val, width, precision):
    integer = abs(int(val * 2 ** precision))
    if val < 0:
        integer = 2 ** (width-1) - integer
    if val >= 0:
        fix_str = bin(integer).replace('0b', '').rjust(width, '0')
    else:
        fix_str = '1'+bin(integer).replace('0b', '').rjust(width-1, '0')
    return fix_str

0
投票

这个fixed_8_to_float函数旨在根据用户francof2a提供的实现将固定int8转换回浮点表示形式

from fxpmath import Fxp

def fixed_8_to_float(binary):
    sum = 0
    multi = 4
    for i in range(1,8):
        sum = sum + int(binary[i]) * multi
        multi/= 2

    if(int(binary[0])==1):
        sum-=8
    return sum

floating_nums = [1 , -1, 2.34,-2.4,-8,0.42]
fixed_nums = [Fxp(x, signed=True, n_word=8, n_frac=4) for x in floating_nums]
binary_strings = [str(x.bin()) for x in fixed_nums]
hex_strings = [str(x.hex()) for x in fixed_nums ]

print(floating_nums)        
print(binary_strings)   
print(hex_strings)   
print([fixed_8_to_float(x) for x in binary_strings])

输出:

[1,-1,2.34,-2.4,-8,0.42]

['00010000', '11110000', '00100101', '11011010', '10000000', '00000110']

['0x10'、'0xF0'、'0x25'、'0xDA'、'0x80'、'0x06']

[1.0,-1.0,2.3125,-2.375,-8.0,0.375]

© www.soinside.com 2019 - 2024. All rights reserved.