如何使用Python将浮点数转换为具有预定义位数的定点数

2024-03-13

我有 numpy 格式的 float 32 个数字(假设是正数)。我想将它们转换为具有预定义位数的定点数以降低精度。

例如,数字 3.1415926 在 matlab 中通过使用函数 num2fixpt 变为 3.25。 命令是 num2fixpt(3.1415926,sfix(5),2^(1 + 2-5), 'Nearest','on') ,表示整数部分 3 位,小数部分 2 位。

我可以使用 Python 做同样的事情吗


如果您了解 IEEE 浮点表示法的工作原理,您就可以做到这一点。基本上你需要转换为 python LONG,执行按位运算符,然后转换回来。例如:

import time,struct,math
long2bits = lambda L: ("".join([str(int(1 << i & L > 0)) for i in range(64)]))[::-1]
double2long = lambda d: struct.unpack("Q",struct.pack("d",d))[0]
double2bits = lambda d: long2bits(double2long(d))
long2double = lambda L: struct.unpack('d',struct.pack('Q',L))[0]
bits2double = lambda b: long2double(bits2long(b))
bits2long=lambda z:sum([bool(z[i] == '1')*2**(len(z)-i-1) for i in range(len(z))[::-1]])

>>> pi = 3.1415926
>>> double2bits(pi)
'0100000000001001001000011111101101001101000100101101100001001010'
>>> bits2long('1111111111111111000000000000000000000000000000000000000000000000')
18446462598732840960L
>>> double2long(pi)
4614256656431372362
>>> long2double(double2long(pi) & 18446462598732840960L)
3.125
>>>

def rshift(x,n=1):
    while n > 0:
        x = 9223372036854775808L | (x >> 1)
        n -= 1
    return x

>>> L = bits2long('1'*12 + '0'*52)
>>> L
18442240474082181120L
>>> long2double(rshift(L,0) & double2long(pi))
2.0
>>> long2double(rshift(L,1) & double2long(pi))
3.0
>>> long2double(rshift(L,4) & double2long(pi))
3.125
>>> long2double(rshift(L,7) & double2long(pi))
3.140625

但这只会截断位数,而不是四舍五入。 rshift 函数是必要的,因为 python 的右移运算符用零填充最左边的空位。请参阅 IEEE 浮点的描述here https://en.wikipedia.org/wiki/Double-precision_floating-point_format.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用Python将浮点数转换为具有预定义位数的定点数 的相关文章

随机推荐