Round up to Second Decimal Place in Python

后端 未结 11 1118
耶瑟儿~
耶瑟儿~ 2020-11-30 07:16

How can I round up a number to the second decimal place in python? For example:

0.022499999999999999

Should round up to 0.03<

相关标签:
11条回答
  • 2020-11-30 07:37

    Python includes the round() function which lets you specify the number of digits you want. From the documentation:

    round(x[, n])

    Return the floating point value x rounded to n digits after the decimal point. If n is omitted, it defaults to zero. The result is a floating point number. Values are rounded to the closest multiple of 10 to the power minus n; if two multiples are equally close, rounding is done away from 0 (so. for example, round(0.5) is 1.0 and round(-0.5) is -1.0).

    So you would want to use round(x, 2) to do normal rounding. To ensure that the number is always rounded up you would need to use the ceil(x) function. Similarly, to round down use floor(x).

    0 讨论(0)
  • 2020-11-30 07:40

    Here is a more general one-liner that works for any digits:

    import math
    def ceil(number, digits) -> float: return math.ceil((10.0 ** digits) * number) / (10.0 ** digits)
    

    Example usage:

    >>> ceil(1.111111, 2)
    1.12
    

    Caveat: as stated by nimeshkiranverma:

    >>> ceil(1.11, 2) 
    1.12  #Because: 1.11 * 100.0 has value 111.00000000000001
    
    0 讨论(0)
  • 2020-11-30 07:41
    def round_up(number, ndigits=None):
        # start by just rounding the number, as sometimes this rounds it up
        result = round(number, ndigits if ndigits else 0)
        if result < number:
            # whoops, the number was rounded down instead, so correct for that
            if ndigits:
                # use the type of number provided, e.g. float, decimal, fraction
                Numerical = type(number)
                # add the digit 1 in the correct decimal place
                result += Numerical(10) ** -ndigits
                # may need to be tweaked slightly if the addition was inexact
                result = round(result, ndigits)
            else:
                result += 1 # same as 10 ** -0 for precision of zero digits
        return result
    
    assert round_up(0.022499999999999999, 2) == 0.03
    assert round_up(0.1111111111111000, 2) == 0.12
    
    assert round_up(1.11, 2) == 1.11
    assert round_up(1e308, 2) == 1e308
    
    0 讨论(0)
  • 2020-11-30 07:43
    from math import ceil
    
    num = 0.1111111111000
    num = ceil(num * 100) / 100.0
    

    See:
    math.ceil documentation
    round documentation - You'll probably want to check this out anyway for future reference

    0 讨论(0)
  • 2020-11-30 07:48
    x = math.ceil(x * 100.0) / 100.0
    
    0 讨论(0)
  • 2020-11-30 07:51

    Updated answer:
    The problem with my original answer, as pointed out in the comments by @jpm, is the behavior at the boundaries. Python 3 makes this even more difficult since it uses "bankers" rounding instead of "old school" rounding. However, in looking into this issue I discovered an even better solution using the decimal library.

    import decimal
    
    def round_up(x, place=0):
        context = decimal.getcontext()
        # get the original setting so we can put it back when we're done
        original_rounding = context.rounding
        # change context to act like ceil()
        context.rounding = decimal.ROUND_CEILING
    
        rounded = round(decimal.Decimal(str(x)), place)
        context.rounding = original_rounding
        return float(rounded)
    

    Or if you really just want a one-liner:

    import decimal
    decimal.getcontext().rounding = decimal.ROUND_CEILING
    
    # here's the one-liner
    float(round(decimal.Decimal(str(0.1111)), ndigits=2))
    >> 0.12
    
    # Note: this only affects the rounding of `Decimal`
    round(0.1111, ndigits=2)
    >> 0.11
    

    Here are some examples:

    round_up(0.022499999999999999, 2)
    >> 0.03
    round_up(0.1111111111111000, 2)
    >> 0.12
    round_up(0.1111111111111000, 3)
    >> 0.112
    
    round_up(3.4)
    >> 4.0
    
    # @jpm - boundaries do what we want
    round_up(0.1, 2)
    >> 0.1
    round_up(1.1, 2)
    >> 1.1
    
    # Note: this still rounds toward `inf`, not "away from zero"
    round_up(2.049, 2)
    >> 2.05
    round_up(-2.0449, 2)
    >> -2.04
    

    We can use it to round to the left of the decimal as well:

    round_up(11, -1)
    >> 20
    

    We don't multiply by 10, thereby avoiding the overflow mentioned in this answer.

    round_up(1.01e308, -307)
    >> 1.1e+308
    

    Original Answer (Not recommended):
    This depends on the behavior you want when considering positive and negative numbers, but if you want something that always rounds to a larger value (e.g. 2.0449 -> 2.05, -2.0449 -> -2.04) then you can do:

    round(x + 0.005, 2)
    

    or a little fancier:

    def round_up(x, place):
        return round(x + 5 * 10**(-1 * (place + 1)), place)
    

    This also seems to work as follows:

    round(144, -1)
    # 140
    round_up(144, -1)
    # 150
    round_up(1e308, -307)
    # 1.1e308
    
    0 讨论(0)
提交回复
热议问题