在Python中很好地表示浮点数
我想将浮点数表示为四舍五入到一定数量的有效数字的字符串,并且从不使用指数格式。本质上,我想显示任何浮点数并确保它“看起来不错”。
这个问题有几个部分:
- 我需要能够指定 有效位数。
- 有效数字位数 需要是可变的,这是不可能的 使用 字符串格式完成 运算符。 [编辑]我已被纠正;字符串格式化运算符可以做到这一点。
- 我需要它以 a 的方式四舍五入 人会期望,而不是某事 就像 1.999999999999
我已经找到了一种方法来做到这一点,尽管它看起来像是一个工作轮并且并不十分完美。 (最大精度为 15 位有效数字。)
>>> def f(number, sigfig):
return ("%.15f" % (round(number, int(-1 * floor(log10(number)) + (sigfig - 1))))).rstrip("0").rstrip(".")
>>> print f(0.1, 1)
0.1
>>> print f(0.0000000000368568, 2)
0.000000000037
>>> print f(756867, 3)
757000
有更好的方法吗?为什么 Python 没有为此提供内置函数?
I want to represent a floating-point number as a string rounded to some number of significant digits, and never using the exponential format. Essentially, I want to display any floating-point number and make sure it “looks nice”.
There are several parts to this problem:
- I need to be able to specify the
number of significant digits. - The number of significant digits
needs to be variable, which can't be
done with with the string formatting
operator. [edit] I've been corrected; the string formatting operator can do this. - I need it to be rounded the way a
person would expect, not something
like 1.999999999999
I've figured out one way of doing this, though it looks like a work-round and it's not quite perfect. (The maximum precision is 15 significant digits.)
>>> def f(number, sigfig):
return ("%.15f" % (round(number, int(-1 * floor(log10(number)) + (sigfig - 1))))).rstrip("0").rstrip(".")
>>> print f(0.1, 1)
0.1
>>> print f(0.0000000000368568, 2)
0.000000000037
>>> print f(756867, 3)
757000
Is there a better way to do this? Why doesn't Python have a built-in function for this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
似乎没有内置的字符串格式化技巧允许您(1)打印第一个有效数字出现在小数点后第 15 位之后的浮点数,以及(2)不以科学记数法表示。这样就剩下手动字符串操作了。
下面我使用
decimal
模块从浮点数中提取十进制数字。float_to_decimal
函数用于将浮点数转换为Decimal
对象。显而易见的方式decimal.Decimal(str(f))
是错误的,因为str(f)
可能会丢失有效数字。float_to_decimal
是从 decimal 模块文档。一旦以整数元组的形式获得十进制数字,下面的代码就会做显而易见的事情:截掉所需数量的有效数字,如果需要的话进行四舍五入,将数字连接在一起形成一个字符串,附加一个符号,放置一个小数点和零根据需要向左或向右。
在底部,您会发现一些我用来测试
f
函数的案例。It appears there is no built-in string formatting trick which allows you to (1) print floats whose first significant digit appears after the 15th decimal place and (2) not in scientific notation. So that leaves manual string manipulation.
Below I use the
decimal
module to extract the decimal digits from the float.The
float_to_decimal
function is used to convert the float to aDecimal
object. The obvious waydecimal.Decimal(str(f))
is wrong becausestr(f)
can lose significant digits.float_to_decimal
was lifted from the decimal module's documentation.Once the decimal digits are obtained as a tuple of ints, the code below does the obvious thing: chop off the desired number of sigificant digits, round up if necessary, join the digits together into a string, tack on a sign, place a decimal point and zeros to the left or right as appropriate.
At the bottom you'll find a few cases I used to test the
f
function.如果您想要浮点精度,则需要使用
decimal
模块,它是 Python 标准库:If you want floating point precision you need to use the
decimal
module, which is part of the Python Standard Library:这是根据给定误差线格式化值的片段。
示例:
Here is a snippet that formats a value according to the given error bars.
Examples:
需要任意精度浮点数才能正确回答这个问题。因此,必须使用 decimal 模块。没有方法可以在不使用指数格式(原始问题的一部分)的情况下将小数转换为字符串,因此我编写了一个函数来做到这一点:
问题是尝试四舍五入到有效数字。 Decimal 的“quantize()”方法不会舍入高于小数点,并且“round()”函数始终返回浮点数。我不知道这些是否是错误,但这意味着舍入无限精度浮点数的唯一方法是将其解析为列表或字符串并手动进行舍入。换句话说,这个问题没有合理的答案。
Arbitrary precision floats are needed to properly answer this question. Therefore using the decimal module is a must. There is no method to convert a decimal to a string without ever using the exponential format (part of the original question), so I wrote a function to do just that:
The problem is trying to round to significant figures. Decimal's "quantize()" method won't round higher than the decimal point, and the "round()" function always returns a float. I don't know if these are bugs, but it means that the only way to round infinite precision floating point numbers is to parse it as a list or string and do the rounding manually. In other words, there is no sane answer to this question.