首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用python将浮点数转换为具有预定义位数的定点

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

Stack Overflow用户
提问于 2016-05-08 12:00:43
回答 4查看 7.1K关注 0票数 5

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

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

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

EN

回答 4

Stack Overflow用户

发布于 2016-05-08 12:16:23

如果你理解IEEE浮点符号的工作原理,你就可以做到这一点。基本上,你需要转换成一个python LONG,做按位运算,然后再转换回来。例如:

代码语言:javascript
复制
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的描述。

票数 3
EN

Stack Overflow用户

发布于 2016-05-08 19:07:01

你可以在没有显式类型转换的情况下舍入到二进制固定精度,这往往会产生大量的解释器开销:

代码语言:javascript
复制
import numpy as np

n_bits = 2
f = (1 << n_bits)

a = np.linspace(1, 2, 11)
a_fix = np.round(a*f)*(1.0/f)

print a
print a_fix

结果:

代码语言:javascript
复制
[ 1.   1.1  1.2  1.3  1.4  1.5  1.6  1.7  1.8  1.9  2. ]
[ 1.    1.    1.25  1.25  1.5   1.5   1.5   1.75  1.75  2.    2.  ]

该示例使用numpy,但这只是为了方便地生成示例值列表。Python内置的round对于单个值同样有效:

代码语言:javascript
复制
x=3.1415926
x_fix = round(x*f)/float(f)
print x_fix

请注意,f和1.0/f都有精确的浮点表示;因此,乘法和除法都是精确的,没有舍入误差。还要注意,在大型数组的情况下,乘以1.0/f比直接除法快3倍左右。

这种方法不控制整数部分的位数,因此,如果您希望在数字太大时对其进行封顶或回绕,则必须进行更多的位移位。

票数 1
EN

Stack Overflow用户

发布于 2020-04-25 22:23:17

您可以使用python 模块来处理python中的分数定点。

模块库:https://github.com/francof2a/fxpmath

代码语言:javascript
复制
from fxpmath import Fxp

pi_fxp = Fxp(None, signed=False, n_word=5, n_frac=2)    # create fixed-point object (3 bit for intefer, 2 for fractional)
pi_fxp.rounding = 'around'                              # define rounding method, default is `trunc`.
pi_fxp(3.1415926)                                       # set value

print(pi_fxp)                                           # printed value = 3.25
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37096090

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档