简体   繁体   English

Python浮点精度格式说明符

[英]Python floating-point precision format specifier

Let's say I have some 32-bit numbers and some 64-bit numbers: 假设我有一些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)

I can print them out with %f but it has extra, unneeded decimals: 我可以用%f打印出来但它有额外的,不需要的小数:

>>> '%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 %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: 我想我应该使用类似于.7的32位值和.15的64位值:

>>> '%.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, eg 34567.375768. 这似乎工作得相当好,但精度数也用于小数位前面的数字,例如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? 总之,将浮点值序列化为文本的正确方法是什么,以便为32位和64位值保留适当的精度,但不使用任何不必要的空间?

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. 我得到了什么.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 您可以尝试使用np.finfo函数来获得与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: 既然你知道你想要多少小数,比如6,只需使用一个rstrip("0")去掉不必要的0:

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

If you're leaning towards %g , perhaps you may want to use a dynamic format such as: 如果你倾向于%g ,也许你可能想要使用动态格式,例如:

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

I am not exactly sure what you are trying to accomplish. 我不确定你想要完成什么。 However, this might help. 但是,这可能会有所帮助。 You wrote 你写了

This seems to work reasonably well, but the precision number is also used up for numbers in front of the decimal place too, eg 34567.375768. 这似乎工作得相当好,但精度数也用于小数位前面的数字,例如34567.375768。

You can use %f instead of g . 您可以使用%f而不是g From the Python docs : 从Python 文档

The precision is a decimal number indicating how many digits should be displayed after the decimal point for a floating point value formatted with 'f' and 'F', or before and after the decimal point for a floating point value formatted with 'g' or 'G'. 精度是一个十进制数,表示对于用'f'和'F'格式化的浮点值,或者在用'g'格式化的浮点值的小数点前后,应在小数点后显示多少位数或'G'。

>>> z = np.float64(4.555555555555555)
>>> "%.3f" % z
'4.556'
>>> q = np.float64(2131234.555555555555555)
>>> "%.3f" % q
'2131234.556'
>>>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM