首页 > 解决方案 > 减少为大数字显示的小数,但不是为小数字

问题描述

格式化浮点数时,是否有任何 python 方法/格式化来减少数字变大时显示的小数位数?

例如,它可以限制显示的数字的位数。下面的例子:

 100.145 ->  100
   2.392 ->    2.39
  34.827 ->   34.8
4599.298 -> 4599

标签: pythonfloating-pointprecisionnumber-formatting

解决方案


更新:

正如 chux 在他的评论中指出的那样,我最初的解决方案不适用于舍入导致进位的边界情况。另外,我没有注意到log10(100) == 2 != 3. 第二个错误很容易找到。为了解决第一个问题,我想出了一个递归。现在它应该可以工作但不再简单了。

import math

def flexible_format(num_in, total_digits):
    try:
        digits_before_decimal = math.floor(math.log10(abs(num_in))) + 1
    except ValueError:
        # if num == 0
        return '0'
    digits_after_decimal = max(0, total_digits - digits_before_decimal)
    # if rounding increases number of digits, we have to format once again
    # after that, an additional rounding doesn't increase the number of digits
    # so we can be sure not to land in an infinite recursion 
    num_out = round(num_in, digits_after_decimal)
    if math.floor(math.log10(abs(num_out))) >= digits_before_decimal:
        return flexible_format(num_out, total_digits)
    return f'{num_out:.{digits_after_decimal}f}'

list_nums =  [-100.145,  2.392, -34.827 , 4599.298, 99.95, 100 ]
for num in list_nums:
    print(flexible_format(num, total_digits=3))
 
# -100
# 2.39
# -34.8
# 4599
# 100
# 100

原始错误解决方案:

我不知道实现这一点的常用功能,但它很容易实现。

import math

def flexible_format(num, total_digits):
    try:
        digits_before_decimal = math.ceil(math.log10(abs(num)))
    except ValueError:
        # if num == 0
        return '0'
    digits_after_decimal = max(0, total_digits - digits_before_decimal)
    return f'{num:.{digits_after_decimal}f}'

list_nums =  [-100.145,  2.392, -34.827 , 4599.298, 0]

for num in list_nums:
    print(flexible_format(num, total_digits=3))

# -100
# 2.39
# -34.8
# 4599
# 0

推荐阅读