Python浮点精度格式说明符 [英] Python floating-point precision format specifier

查看:311
本文介绍了Python浮点精度格式说明符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一些32位数字和一些64位数字:

 >>> import numpy as np 
>>> w = np.float32(2.4)
>>> x = np.float32(4.555555555555555)
>>> y = np.float64(2.4)
>>> z = np.float64(4.555555555555555)

我可以用



 >>> '%f%f%f%f'%(w,x,y,z)
'2.400000 4.555555 2.400000 4.555556'

我可以使用%g ,但它似乎有一个小的默认精度:

 >>> '%g%g%g%g'%(w,x,y,z)
'2.4 4.55556 2.4 4.55556'

我正在考虑为32位值和 .15 .7

 >>>对于64位值, '%.7g%.7g%.15g%.15g'%(w,x,y,z)
'2.4 4.555555 2.4 4.55555555555556'

这似乎工作得相当好,但精确数字也用于小数点前的数字,例如总而言之,将浮点值序列化为文本的正确方法是什么,从而保留了32位和64位值的适当精度,但是却不能保证32位和64位值的精度没有使用任何不必要的空间?



更新

输出应该是:

  number float32 float64 
5 5 5
0.1 0.1 0.1
2.4 2.4 2.4
4.555555555555555 4.5555553 4.5555555555555554
12345678.92345678635 12345679.0 12345678.923456786

我用.7 / .16得到的。这实际上看起来不错:

 >>> v32 = np.array([5,0.1,2.4,4.555555555555555,12345678.92345678635],dtype = np.float32)
>>> v64 = np.array([5,0.1,2.4,4.555555555555555,12345678.92345678635],dtype = np.float64)
>>> ('%.7g'* len(v32))%tuple(v32)
'5 0.1 2.4 4.555555 1.234568e + 07'
>>> ('%.16g'* len(v64))%tuple(v64)
'5 0.1 2.4 4.555555555555555 12345678.92345679'


解决方案

您可以尝试使用 np.finfo 函数来获得与你的float相对应的精度

  finfo32 = np.finfo(np.float32)
finfo64 = np.finfo(np.float64)

finfo32.resolution = 1e-6
finfo64.resolution = 1e-15

现在你知道你要多少小数,说,6,只是使用 rstrip(0)摆脱不必要的0:



<$ p $打印(%.6f%your_float).strip(0)

如果您倾向于%g ,也许您可​​能需要使用动态格式,例如:

 >>> strf = lambda v:(%%。%ig%max(np.ceil(np.log10(v)),7))%v 
>>> strf(123.456789)
'123.45679'
>>> strf(123456789.12345)
'123456789'


Let's say I have some 32-bit numbers and some 64-bit numbers:

>>> import numpy as np
>>> w = np.float32(2.4)
>>> x = np.float32(4.555555555555555)
>>> y = np.float64(2.4)
>>> z = np.float64(4.555555555555555)

I can print them out with %f but it has extra, unneeded decimals:

>>> '%f %f %f %f' % (w, x, y, z)
'2.400000 4.555555 2.400000 4.555556'

I can use %g but it seems to have a small default precision:

>>> '%g %g %g %g' % (w, x, y, z)
'2.4 4.55556 2.4 4.55556'

I was thinking I should use something like .7 for 32-bit values and .15 for 64-bit values:

>>> '%.7g %.7g %.15g %.15g' % (w, x, y, z)
'2.4 4.555555 2.4 4.55555555555556'

This seems to work reasonably well, but the precision number is also used up for numbers in front of the decimal place too, e.g. 34567.375768.

In summary, what is the correct way to serialize floating-point values to text such that it preserves appropriate precision for 32-bit and 64-bit values but doesn't use any unnecessary space?

Update:

Examples of what I think the output should be:

number                float32     float64
5                     5           5
0.1                   0.1         0.1
2.4                   2.4         2.4
4.555555555555555     4.5555553   4.5555555555555554
12345678.92345678635  12345679.0  12345678.923456786

What I get with .7/.16. This actually looks okay:

>>> v32 = np.array([5, 0.1, 2.4, 4.555555555555555, 12345678.92345678635], dtype=np.float32)
>>> v64 = np.array([5, 0.1, 2.4, 4.555555555555555, 12345678.92345678635], dtype=np.float64)
>>> ('%.7g ' * len(v32)) % tuple(v32)
'5 0.1 2.4 4.555555 1.234568e+07 '
>>> ('%.16g ' * len(v64)) % tuple(v64)
'5 0.1 2.4 4.555555555555555 12345678.92345679 '

解决方案

You could try to use the np.finfo function to get the precision corresponding to your float

finfo32 = np.finfo(np.float32)
finfo64 = np.finfo(np.float64)

finfo32.resolution = 1e-6
finfo64.resolution = 1e-15

Now that you know how many decimals you want, say, 6, just use a rstrip("0") to get rid of the unnecessary 0s:

print ("%.6f" % your_float).strip("0")

If you're leaning towards %g, perhaps you may want to use a dynamic format such as:

>>> strf = lambda v: ("%%.%ig" % max(np.ceil(np.log10(v)), 7)) % v
>>> strf(123.456789)
'123.45679'
>>> strf(123456789.12345)
'123456789'

这篇关于Python浮点精度格式说明符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆