基于浮点值的可变精度Python浮点格式

问题描述 投票:0回答:3

我希望这个标题不会让人们失望,因为据我所知,这不是重复的。

情况:我有一个数字 0 .. x .. 1,它可能非常小,所以 1 >> n (例如 0.00001321)。

问题:我想使用 4 个有效小数位打印这个数字,因此用精度“4”打印 0.00001 将是“0.0000”。我想要的是“0.00001321”。同样,如果数字是“0.3”我想打印“0.3000”。 示例:

value string representation v = 0.00001231231231 format_v(v) == "0.00001231" v = 0.00012312312312 format_v(v) == "0.0001231" v = 0.00123123123123 format_v(v) == "0.001231" v = 0.01231231231231 format_v(v) == "0.01231" v = 0.12312312312312 format_v(v) == "0.1231" def format_v(v): # that's the big question ... pass

有办法做到这一点吗?

python python-3.x floating-point precision
3个回答
1
投票

from decimal import Decimal, ROUND_HALF_UP def format_v(v): precision = 4 str_v = format(v, '.50f') for i, v in enumerate(str_v[2:]): if v != "0": break return str_v[:i+2+precision] def format_v_round(val): precision = 4 for i, v in enumerate(format(val, '.50f')[2:]): if v != "0": break dot = '.'+'0'*(i+precision) dec = Decimal(val).quantize(Decimal(dot), rounding=ROUND_HALF_UP) return format(dec, '.50f')[:2+i+precision] for val in [0.0001234655, 0.012, 0.1, 0.00000011233]: print("format_v(", val, "):", format_v(val)) print("\n\n") for val in [0.000123455, 0.000123445, 0.000123465, 0.012, 0.111155, 0.111145, 0.11115, 0.11114, 0.1, 0.00000011233]: print("format_v_round(", val, "):", format_v_round(val))

出:

format_v( 0.0001234655 ): 0.0001234 format_v( 0.012 ): 0.01200 format_v( 0.1 ): 0.1000 format_v( 1.1233e-07 ): 0.0000001123 format_v_round( 0.000123455 ): 0.0001235 format_v_round( 0.000123445 ): 0.0001234 format_v_round( 0.000123465 ): 0.0001235 format_v_round( 0.012 ): 0.01200 format_v_round( 0.111155 ): 0.1112 format_v_round( 0.111145 ): 0.1111 format_v_round( 0.11115 ): 0.1111 format_v_round( 0.11114 ): 0.1111 format_v_round( 0.1 ): 0.1000 format_v_round( 1.1233e-07 ): 0.0000001123



0
投票

def format_v(v): s=format(v, '.50f') return s[:6+len(list((itertools.takewhile(lambda x: x=='0', s[2:]))))]

但是说实话,你为什么不使用指数表示法呢?

def format_v(v): s=format(v, '.50f') return f'{float(s):10.4e}'

编辑

我添加了对字符串的转换,这是我在之前的建议中错误地忽略的,并在下面放置了一个舍入版本。只是为了稍微改进一下,这个版本接受一个可选的

precision

参数,而不是使用不同的、更数学的方法来计算字符串中的零:

def format_round_v(v, precision=4):
    digits=precision + abs(round(math.log(v, 10)))
    quantizer = "." + "0" * digits
    d=Decimal(v).quantize(Decimal(quantizer),ROUND_HALF_UP)
    return format(d, '.50f')[:2+digits]



0
投票

import decimal as d d.getcontext().prec = 10 def format_v(v): return round(d.Decimal(v),4) v = 0.00001231231231 print(format_v(v))

© www.soinside.com 2019 - 2024. All rights reserved.