Pet*_*ham 130 python math rounding
我需要对浮点数进行舍入以在UI中显示.例如,一个重要人物:
1234 - > 1000
0.12 - > 0.1
0.012 - > 0.01
0.062 - > 0.06
6253 - > 6000
1999年 - > 2000年
有没有一种很好的方法可以使用Python库来实现这一点,还是我必须自己编写?
Evg*_*eny 134
您可以使用负数来舍入整数:
>>> round(1234, -3)
1000.0
Run Code Online (Sandbox Code Playgroud)
因此,如果您只需要最重要的数字:
>>> from math import log10, floor
>>> def round_to_1(x):
... return round(x, -int(floor(log10(abs(x)))))
...
>>> round_to_1(0.0232)
0.02
>>> round_to_1(1234243)
1000000.0
>>> round_to_1(13)
10.0
>>> round_to_1(4)
4.0
>>> round_to_1(19)
20.0
Run Code Online (Sandbox Code Playgroud)
如果它大于1,你可能需要注意将float转换为整数.
Pet*_*ham 95
字符串格式化中的%g将浮动格式化为一些有效数字.它有时会使用'e'科学记数法,因此将圆形字符串转换回浮点数然后通过%s字符串格式转换.
>>> '%s' % float('%.1g' % 1234)
'1000'
>>> '%s' % float('%.1g' % 0.12)
'0.1'
>>> '%s' % float('%.1g' % 0.012)
'0.01'
>>> '%s' % float('%.1g' % 0.062)
'0.06'
>>> '%s' % float('%.1g' % 6253)
'6000.0'
>>> '%s' % float('%.1g' % 1999)
'2000.0'
Run Code Online (Sandbox Code Playgroud)
小智 46
如果您想要除1个有效小数之外(否则与Evgeny相同):
>>> from math import log10, floor
>>> def round_sig(x, sig=2):
... return round(x, sig-int(floor(log10(abs(x))))-1)
...
>>> round_sig(0.0232)
0.023
>>> round_sig(0.0232, 1)
0.02
>>> round_sig(1234243, 3)
1230000.0
Run Code Online (Sandbox Code Playgroud)
小智 17
print('{:g}'.format(float('{:.1g}'.format(12.345))))
Run Code Online (Sandbox Code Playgroud)
此解决方案与所有其他解决方案不同,因为:
对于任意数量n的有效数字,您可以使用:
print('{:g}'.format(float('{:.{p}g}'.format(i, p=n))))
Run Code Online (Sandbox Code Playgroud)
测试:
a = [1234, 0.12, 0.012, 0.062, 6253, 1999, -3.14, 0., -48.01, 0.75]
b = ['{:g}'.format(float('{:.1g}'.format(i))) for i in a]
# b == ['1000', '0.1', '0.01', '0.06', '6000', '2000', '-3', '0', '-50', '0.8']
Run Code Online (Sandbox Code Playgroud)
注意:使用此解决方案,无法从输入动态调整有效数字的数量,因为没有标准方法可以区分具有不同数量的尾随零(3.14 == 3.1400)的数字.如果需要这样做,则需要非标准函数,如精度软件包中提供的函数.
Sam*_*son 10
为了直接回答这个问题,这是我使用R 函数命名的版本:
import math
def signif(x, digits=6):
if x == 0 or not math.isfinite(x):
return x
digits -= math.ceil(math.log10(abs(x)))
return round(x, digits)
Run Code Online (Sandbox Code Playgroud)
我发布此答案的主要原因是评论抱怨“0.075”四舍五入为 0.07 而不是 0.08。正如“C 新手”所指出的那样,这是由于具有有限精度和基数 2 表示的浮点运算的组合。实际可以表示的最接近 0.075 的数字略小,因此四舍五入的结果与您可能天真地预期的不同。
另请注意,这适用于任何非十进制浮点运算的使用,例如 C 和 Java 都有相同的问题。
为了更详细地显示,我们要求 Python 将数字格式化为“十六进制”格式:
0.075.hex()
Run Code Online (Sandbox Code Playgroud)
这给了我们:0x1.3333333333333p-4. 这样做的原因是正常的十进制表示通常涉及四舍五入,因此不是计算机实际“看到”数字的方式。如果您不习惯这种格式,可以参考Python 文档和C 标准.
为了展示这些数字是如何工作的,我们可以通过执行以下操作回到我们的起点:
0x13333333333333 / 16**13 * 2**-4
Run Code Online (Sandbox Code Playgroud)
应该打印出来0.075。 16**13是因为小数点后有 13 个十六进制数字,而且2**-4是因为十六进制指数是以 2 为底的。
现在我们对如何表示浮点数有了一些了解,我们可以使用该decimal模块为我们提供更高的精度,向我们展示正在发生的事情:
from decimal import Decimal
Decimal(0x13333333333333) / 16**13 / 2**4
Run Code Online (Sandbox Code Playgroud)
给予:0.07499999999999999722444243844并希望解释为什么round(0.075, 2)评估为0.07
我已经创建了包含精确度的包,可以满足您的需求.它允许您给出数字或多或少的重要数字.
它还输出具有指定数量的有效数字的标准,科学和工程符号.
在接受的答案中有一条线
>>> round_to_1(1234243)
1000000.0
Run Code Online (Sandbox Code Playgroud)
这实际上指定了8个无花果.对于数字1234243,我的库只显示一个重要数字:
>>> from to_precision import to_precision
>>> to_precision(1234243, 1, 'std')
'1000000'
>>> to_precision(1234243, 1, 'sci')
'1e6'
>>> to_precision(1234243, 1, 'eng')
'1e6'
Run Code Online (Sandbox Code Playgroud)
它还将围绕最后一个有效数字,并且如果未指定表示法,则可以自动选择要使用的符号:
>>> to_precision(599, 2)
'600'
>>> to_precision(1164, 2)
'1.2e3'
Run Code Online (Sandbox Code Playgroud)
发布的答案是给出的最佳答案,但它有许多限制,并且不会产生技术上正确的有效数字。
numpy.format_float_positional直接支持所需的行为。以下片段返回格式化x为 4 位有效数字的浮点数,并抑制科学记数法。
import numpy as np
x=12345.6
np.format_float_positional(x, precision=4, unique=False, fractional=False, trim='k')
> 12340.
Run Code Online (Sandbox Code Playgroud)
要将整数舍入为1有效数字,基本思路是将其转换为在点之前有1位数的浮点,然后将其转换回原始整数大小.
要做到这一点,我们需要知道10的最大功率小于整数.我们可以使用log 10功能的楼层.
Run Code Online (Sandbox Code Playgroud)from math import log10, floor def round_int(i,places): if i == 0: return 0 isign = i/abs(i) i = abs(i) if i < 1: return 0 max10exp = floor(log10(i)) if max10exp+1 < places: return i sig10pow = 10**(max10exp-places+1) floated = i*1.0/sig10pow defloated = round(floated)*sig10pow return int(defloated*isign)
def round_to_n(x, n):
if not x: return 0
power = -int(math.floor(math.log10(abs(x)))) + (n - 1)
factor = (10 ** power)
return round(x * factor) / factor
round_to_n(0.075, 1) # 0.08
round_to_n(0, 1) # 0
round_to_n(-1e15 - 1, 16) # 1000000000000001.0
Run Code Online (Sandbox Code Playgroud)
希望能采纳上面所有答案中最好的答案(减去能够将其作为单行 lambda ;))。尚未探索,请随意编辑此答案:
round_to_n(1e15 + 1, 11) # 999999999999999.9
Run Code Online (Sandbox Code Playgroud)