以一致或固定的精度打印数字

时间:2016-04-04 21:16:44

标签: python format floating-accuracy

这三个数字1.2, 0.0034, 56000都有一个共同点:准确度两位数。让我们说我想报告几个非常不同的设备的计算带宽,范围从每秒千字节到每秒千兆字节,所有这些都变化高达%10。我的读者快速掌握结果的最简单方法是将所有内容转换为公共单位(比如MB / s),排列小数点,

    1.2
    0.0034
56000

并避免打印无关数字;如果我的计算值是1.193225,0.00344791和56188.5622,那么我的读者只需要看到上面的内容 - 其余的是噪音。尽管浮点数的格式选项很多,但Python似乎没有一种干净的方法来打印具有固定精度的数字。最好的方法是什么?

关于评分这个问题的说明:我会在第一个答案中选择最好的(即简单,易懂,优雅)答案。不需要急于求成。

3 个答案:

答案 0 :(得分:2)

import math


def round_s(n):
    if not n:
        return n
    e = int(math.floor(math.log10(abs(n)))) - 1
    return round(n, -e)


def fmt(n, size):
    return '{n:{size}f}'.format(size=size, n=n).rstrip('0').rstrip('.')


numbers = [
    1.193225,
    1.0,
    0,
    -1.0,
    0.00344791,
    -0.00344791,
    56188.5622,
    -56188.5622,
]

for n in numbers:
    print '{:12.5f} => {}'.format(n, fmt(round_s(n), 14))

输出:

     1.19322 =>       1.2
     1.00000 =>       1
     0.00000 =>       0
    -1.00000 =>      -1
     0.00345 =>       0.0034
    -0.00345 =>      -0.0034
 56188.56220 =>   56000
-56188.56220 =>  -56000

你走了。

答案 1 :(得分:1)

我会结合两个堆栈溢出答案(假设每个都是执行此任务的两半的最佳方法): Round to a specific number of significant figuresalign the numbers using the formatting language

from math import log10, floor
NUM_DIGITS = 2 # Number of significant digits

# An example input
number = 1.193225

# Round the number
rounded = round(number, -int(floor(log10(number))) + (NUM_DIGITS - 1)) 

# Print aligned to the decimal point
print('{part[0]:>3}.{part[1]:<3}'.format(part=str(rounded).split('.')))

您必须将字符串格式化程序中的两个宽度调整为至少与数字的最宽整数和小数部分一样宽。完整的解释可以在相应的链接页面上找到。

答案 2 :(得分:0)

如果您想使用任何长度的字符串,您需要知道小数点前的位数的最大数量:

def my_format(numbers):
    mxi = max(len(str(num).split(".")[0]) for num in numbers)
    for num in numbers:
        if isinstance(num, float):
            t = "{}".format(float("{:.2g}".format(num)))
            print(t.rjust((mxi + len(t.split(".")[-1]) + 1), " "))
        else:
            print("{:{mx}}".format(num, mx=mxi)

哪个应该对齐任何长度:

In [10]: numbers = [
    1.193225,
    1.0,
    0,
    -1.0,
    0.00344791,
    -0.00344791,
    56188.5622,
    -56188.5622,
    123456789,
    12,
    123]

In [11]: my_format(numbers)
        1.2
        1.0
        0
       -1.0
        0.0034
       -0.0034
    56000.0
   -56000.0
123456789
       12
      123