How to properly round up half float numbers in Python?

python round half up
python round up
round python 3
python round up to 2 decimal places
python 3 round to 2 decimal places
python round to nearest 5
python truncate float
python round to nearest 10

I am facing a strange behavior of the round() function:

for i in range(1, 15, 2):
    n = i / 2
    print(n, "=>", round(n))

This code prints:

0.5 => 0
1.5 => 2
2.5 => 2
3.5 => 4
4.5 => 4
5.5 => 6
6.5 => 6

I expected the floating values to be always rounded up, but instead, it is rounded to the nearest even number.

Why such behavior, and what is the best way to get the correct result?

I tried to use the fractions but the result is the same.

The Numeric Types section documents this behaviour explicitly:

round(x[, n]) x rounded to n digits, rounding half to even. If n is omitted, it defaults to 0.

Note the rounding half to even. This is also called bankers rounding; instead of always rounding up or down (compounding rounding errors), by rounding to the nearest even number you average out rounding errors.

If you need more control over the rounding behaviour, use the decimal module, which lets you specify exactly what rounding strategy should be used.

For example, to round up from half:

>>> from decimal import localcontext, Decimal, ROUND_HALF_UP
>>> with localcontext() as ctx:
...     ctx.rounding = ROUND_HALF_UP
...     for i in range(1, 15, 2):
...         n = Decimal(i) / 2
...         print(n, '=>', n.to_integral_value())
...
0.5 => 1
1.5 => 2
2.5 => 3
3.5 => 4
4.5 => 5
5.5 => 6
6.5 => 7

How to Round Numbers in Python – Real Python, This article is not a treatise on numeric precision in computing, although we will touch Likewise, truncating a negative number rounds that number up. “​rounding half to even strategy,” failed to round 2.675 to two decimal places correctly. The round() function works by accepting two parameters. The first is the number you want to round. The second is the number of decimal places to round to. If you round 8.8333333333339 to 2 decimals, the correct answer is 8.83, not 8.84.

For example:

from decimal import Decimal, ROUND_HALF_UP

Decimal(1.5).quantize(0, ROUND_HALF_UP)

# This also works for rounding to the integer part:
Decimal(1.5).to_integral_value(rounding=ROUND_HALF_UP)

How to Round Numbers in Python|Python round() function, Python's round() method to return a floating point number rounded off come to your mind - How do you handle situations where the number  In general, two rather simple rules are applied for rounding, you may remember them from school. The digits 0 to 4 lead to rounding down, and the numbers 5 to 9 lead to rounding up. The table below shows a selection of use cases.

You can use this:

import math
def normal_round(n):
    if n - math.floor(n) < 0.5:
        return math.floor(n)
    return math.ceil(n)

It will round number up or down properly.

Rounding Numbers in Python, As soon as floating point numbers or fractions, as well as divisions, come into rounding up, rounding down, rounding half-up, rounding half-down, as well as four popular modules that can help you properly deal with floating point numbers. Round the number n to p decimal places by first shifting the decimal point in n by p places by multiplying n by 10ᵖ (10 raised to the pth power) to get a new number m. Then look at the digit d in the first decimal place of m. If d is less than 5, round m down to the nearest integer. Otherwise, round m up.

round() will round either up or down, depending on if the number is even or odd. A simple way to only round up is:

int(num + 0.5)

If you want this to work properly for negative numbers use:

((num > 0) - (num < 0)) * int(abs(num) + 0.5)

Note, this can mess up for large numbers or really precise numbers like 5000000000000001.0 and 0.49999999999999994.

9.4. decimal, The decimal module provides support for decimal floating point arithmetic. Decimals interact well with much of the rest of Python. The result is correctly rounded using the ROUND_HALF_EVEN rounding mode. This can leave up to 3 digits to the left of the decimal place and may require the addition of  Should have writen when the number does not have a finite decimal representation in base-10, which will happen with any fraction when the denominator is not divisible by 2 or 5. (Granted "the fraction cannot be represented in base 10 exactly. The number is, of course, in base 10." isn't exactly correct either. Numbers don't have bases.

The behavior you are seeing is typical IEEE 754 rounding behavior. If it has to choose between two numbers that are equally different from the input, it always picks the even one. The advantage of this behavior is that the average rounding effect is zero - equally many numbers round up and down. If you round the half way numbers in a consistent direction the rounding will affect the expected value.

The behavior you are seeing is correct if the objective is fair rounding, but that is not always what is needed.

One trick to get the type of rounding you want is to add 0.5 and then take the floor. For example, adding 0.5 to 2.5 gives 3, with floor 3.

round() function in Python, How to properly round up half float numbers in Pyt It can represent numbers like 2.675 precisely, unlike Python floats where 2.675 is really  Example 2: Round a number to given ndigits places. When you run the program, the output will be: Here, both numbers result to the same output 2.67, when 2.675 should have been rounded to 2.68. This isn't a bug but it is because, most decimal numbers cannot be represented exactly as a float.

How to round down to 2 decimals a float using Python?, How do you round up a floating number in Python? The final number is rounded up if the next digit is 5 or more. Python program that uses round number = 1.23456 # Use round built-in. # This rounds up or down depending on the last digit.

Python Round Up and Down (Math Round), How do you limit a float to two decimal places in Python? Unfortunately, most decimal fractions cannot be represented exactly as binary fractions. A consequence is that, in general, the decimal floating-point numbers you enter are only approximated by the binary floating-point numbers actually stored in the machine. The problem is easier to understand at first in base 10. Consider the fraction 1/3.

Python round(), Python provides an inbuilt function round() which rounds off to the given number of digits and returns the floating point number, if no number of digits ..b) if a decimal number is given , then it will round off to the ceil integer after that if and PEP8 · Introduction to Pandas in Python · Program to print half Diamond star pattern. There are three ways to round numbers to a certain number of decimal places. To round up and down we use Python's round() function. The first argument we give that function is the number to round. The second argument the number of decimal places to round to. Python has no function that always rounds decimal digits up (9.232 into 9.24).

Comments
  • can't explain the behaviour of round() but you could use math.ceil() if you always want to round up
  • @yurib I would like 1.3 to be rounded down to 1, so I can not use ceil().
  • Possible duplicate of Limiting floats to two decimal points
  • Many days have passed since I studied error analysis. However If I recall correctly, the rounding of 5*10**-k depends on the digit preceding it. By rounding up for uneven digits and down for even digits, you get a positive error half the time and an even error half the time (in theory). When you perform many additions, those errors can cancel each-other
  • IEEE 754 rounding half to even is also described at en.wikipedia.org/wiki/Rounding#Round_half_to_even
  • In your example, is there a benefit to modifying the local context as opposed to just using the rounding argument as in: n.to_integral_value(rounding=ROUND_HALF_UP)?
  • @dhobbs: setting the context once is clearer in intent, but from a technical point of view there is no difference.
  • There are some subtleties that aren't addressed by this solution. E.g., what result does this give if num = -2.4? What about num = 0.49999999999999994? num = 5000000000000001.0? On a typical machine using IEEE 754 format and semantics, this solution gives the wrong answer for all three of these cases.
  • @Mark Dickinson I've updated the post to mention this. Thanks
  • Now x.499999999 will be subject to half-even rounding, and will (half the time, assuming floating point precision issues don't force it one way or the other) get rounded up. That's worse than the initial scenario, as you're now rounding to the more distant number.