【问题标题】:Round a floating point number to n digits ignoring leading zeros and preserving them将浮点数舍入为 n 位,忽略前导零并保留它们
【发布时间】:2019-06-26 15:50:31
【问题描述】:

浮点数 = 11.0000123456789

我想将上面的浮点数四舍五入为 11.00001235。所以我希望浮点数的基数部分舍入为 4 位,同时忽略并保留前导零并在末尾添加回有效数字。

我有以下内容,它简短而甜蜜,但感觉有点像变通。

import decimal

decimal.getcontext().prec = 4
significand, base = str(11.0000123456789).split('.')
fp = significand + str(decimal.Decimal('.' + base) + 0)[1:]  # I need to add 0 here for it to work
print(fp)

我真的找不到具体问题的答案。我想知道实现这一目标的最 Pythonic 方式是什么,或者我所拥有的是否足够体面。我觉得有点粗制滥造。

编辑:前导零的数量未知,我选择了四个作为示例。所以我不认为字符串格式化会起作用。

【问题讨论】:

    标签: python decimal rounding


    【解决方案1】:

    我认为这是解决您的问题的最 Pythonic 方式。试试这个,

    >>> import re
    >>>
    >>> float_val = 11.0000123456789
    >>> keep_places = 4
    >>>
    >>> regEX = f'[0-9]+\.[0]+{"[0-9]" * keep_places}'
    >>> expected_val = re.search(regEX, str(float_val)).group()
    >>>
    >>> print(expected_val)
    '11.00001234'
    

    最简单的方法是创建Regular expression operations,这就是我使用它来解决您的问题的方式。让我们把它分成 4 个部分。

    1. [0-9]+
    2. \.
    3. [0]+
    4. [0-9] * keep_places

    (1)。 [0-9] 表示在 0 到 9 之间只选择一位。我们需要在小数点前多位。这就是我们添加[0-9]+ 的原因。如果小数点前没有任何整数,则添加* 而不是+,它会检查零次或多次出现。如果你使用+ 意味着你必须有一个或多个值。

    (2)。 . 这个点是一个特殊字符,用于从给定字符串中选择除换行符以外的任何字符。我们需要捕获也是一个点的小数点。如果我们的字符串有这些特殊字符(在我们的例子中是小数点),我们使用\ 来匹配这些字符。这就是我们使用\. 的原因,它现在可以匹配我们的小数点。

    (3)。 [0]+,这将匹配我们字符串中的所有零。

    (4)。 [0-9] * keep_places,这只是一个字符串乘法。对于这个问题keep_places 是4,这意味着我们得到这种输出[0-9][0-9][0-9][0-9]。但是在Regular expression operations 中,它只选择四位数字,每个数字在0 到9 之间。另外,对于这个问题,您使用[0-9] 或[1-9] 并不重要。因为我们已经捕获了零,它开始从1 中寻找其他整数。

    如果您打印regEX,您将看到[0-9]+\.[0]+[0-9][0-9][0-9][0-9] 类型的字符串。它仅匹配 <any_number><dot><all_zeros_before_the__non_zero_integer><4_digit_after_last_zero> 类型的模式。你可以测试这个表达式online。

    【讨论】:

    • 我想使用它,但如果小数点后前导零的数量发生变化,它将不起作用。
    • 你试过@probat吗?只需将keep_points 更改为4,您将获得11.0000。
    • 不,我没有尝试过,但我知道它的作用。这不是我要求的行为。我想在小数点后直接保留所有前导零,然后将非零数字四舍五入,同时保留 n 位数字,其中 n 可以是任何数字。此外,前导零的数量可以是任意数量的零。我只是为这个例子选择了四个前导零。在我发布的这个例子中,我希望最终的浮点数是11.00001235,但是如果初始浮点数有 9 个前导零,你给我的将不起作用。我必须始终更新 keep_point 变量。它需要与所有浮点数一起使用。
    • 感谢@Kushan,非常感谢您抽出时间提供帮助。
    • 不客气@probat,我更新了我的答案。请检查并告诉我。我希望你能明白。
    【解决方案2】:

    编辑:对于未知数量的 0,我认为没有比

    更好的选择
    import re
    some_float = 11.00001203456789
    how_many_to_keep = 4
    regex = r"0[1-9]"
    float_part = str(some_float).split(".")[1]
    float_limiter = re.search(regex,float_part).start() if float_part.startswith("0") else -1
    print(f'{some_float:2.{float_limiter+1+how_many_to_keep}f}')
    

    使用表达式float_limiter+1+how_many_to_keep实时计算0的个数,并用作格式参数。这有点难看,但现在在所有情况下都返回正确答案。输出是

    11.00001235

    【讨论】:

    • 我应该提到前导零的数量是未知的。我只是为示例选择了四个前导零,因此字符串格式不起作用。
    • 抱歉,我的注意力不集中,编辑将达到您的目标
    • 感谢@rotem 确实有效。我希望有更多的pythonic哈哈,但我所做的很可能不是很常见。
    • @rotemtal,当我将11.00001023456789 分配给some_float 时,输出为11.0000102346。它在最后一个零之后显示6 字符。
    • @KushanGunasekera 正确,我已经编辑了我的代码,它现在应该在这些情况下返回正确的值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-20
    • 1970-01-01
    • 1970-01-01
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多