简体   繁体   English

在 python 中四舍五入到有效数字

[英]Round to significant figures in python

I want to round like this 42949672 -> 42949700, 2147483647 -> 2147480000, 4252017622 -> 4252020000 etc.我想像这样四舍五入 42949672 -> 42949700、2147483647 -> 2147480000、4252017622 -> 4252020000 等。

I tried to use following, but only works for the first one.我尝试使用以下,但只适用于第一个。 How can I make a more general one?我怎样才能做一个更通用的? thanks谢谢

round(42949672, -2)

I want to round like this 42949672 -> 42949700, 2147483647 -> 2147480000, 4252017622 -> 4252020000 etc.我想像这样四舍五入为42949672-> 42949700,2147483647-> 2147480000,4252017622-> 4252020000等

I tried to use following , but only works for the first one.我尝试使用following,但仅适用于第一个。 How can I make a more general one?我该如何做一个更通用的? thanks谢谢

round(42949672, -2)

I want to round like this 42949672 -> 42949700, 2147483647 -> 2147480000, 4252017622 -> 4252020000 etc.我想像这样四舍五入为42949672-> 42949700,2147483647-> 2147480000,4252017622-> 4252020000等

I tried to use following , but only works for the first one.我尝试使用following,但仅适用于第一个。 How can I make a more general one?我该如何做一个更通用的? thanks谢谢

round(42949672, -2)

I want to round like this 42949672 -> 42949700, 2147483647 -> 2147480000, 4252017622 -> 4252020000 etc.我想像这样四舍五入为42949672-> 42949700,2147483647-> 2147480000,4252017622-> 4252020000等

I tried to use following , but only works for the first one.我尝试使用following,但仅适用于第一个。 How can I make a more general one?我该如何做一个更通用的? thanks谢谢

round(42949672, -2)

I want to round like this 42949672 -> 42949700, 2147483647 -> 2147480000, 4252017622 -> 4252020000 etc.我想像这样四舍五入为42949672-> 42949700,2147483647-> 2147480000,4252017622-> 4252020000等

I tried to use following , but only works for the first one.我尝试使用following,但仅适用于第一个。 How can I make a more general one?我该如何做一个更通用的? thanks谢谢

round(42949672, -2)

Expanded on @david-joy's function.在@david-joy 的 function 上扩展。 Indeed, it did not work properly in the else clause, and actually not all cases were covered in the if clause.事实上,它在 else 子句中不能正常工作,实际上并不是所有情况都包含在 if 子句中。 So here is my function.所以这是我的 function。

def round_to_nsf(number, nsf=2):
    integer_part = math.floor(number)
    if integer_part > 0:
        integer_part_len = len(str(integer_part))
        return round(number, nsf-integer_part_len)
    else:
        st = {'1', '2', '3', '4', '5', '6', '7', '8', '9'}
        index = next((i for i, ch in enumerate(str(number)) if ch in st), None)
        return round(number, index)

These work for me, for ints and floats, both positive and negative.这些对我有用,适用于正数和负数的整数和浮点数。 If desired they may be modified to preserve the original int or float type by applying isinstance() to x and then return int() or float().如果需要,可以通过将 isinstance() 应用于 x 然后返回 int() 或 float() 来修改它们以保留原始 int 或 float 类型。

Note that format beyond around 14 digits can give unexpected results.请注意,超过 14 位数字的格式可能会产生意想不到的结果。

# Option 1: use math
import math
def rnd1(x, sigdig=14):
    """Round x to sigdig significant digits"""
    # n = digits to the left of decimal, can be negative
    n = math.floor(math.log10(abs(x))) + 1
    return round(x, sigdig - n)

# Option 2: use format which also rounds
def rnd2(x, sigdig=14):
    """Round x to sigdig significant digits"""
    f = f'{{:.{sigdig - 1}E}}'
    s = f.format(x)
    return float(s)

# Bonus: use format to truncate
def sig(x, sigdig=14):
    """Truncate x to sigdig significant digits"""
    f = f'{{:.{sigdig}E}}'
    s = f.format(x)
    decimal= 1
    minus = 1 if x < 0 else 0
    s = ''.join( (s[:sigdig + minus + decimal], s[s.index('E'):]) )
    return float(s)

# Unexpected format results with large number of significant digits
>>> '{:.20E}'.format(10**-1)
'1.00000000000000005551E-01'

>>> '{:.20E}'.format(10**-10)
'1.00000000000000003643E-10'

>>> '{:.20E}'.format(10**-20)
'9.99999999999999945153E-21'

>>> n = .123456789012345678901234567890
>>> '{:.20E}'.format(n)
'1.23456789012345677370E-01'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM