+ 3

[Solved] Is it possible to change the default rounding method in Python?

In one of the programming puzzle in codeabbey, it asks the numbers to be rounding in "Rounding half away from zero". In short, if the fractional part of x is exactly 0.5, then y = x + 0.5 if x is positive, and y = x − 0.5 if x is negative. Example 1: 123.5 becomes 124 Example 2: -123.5 becomes -124 https://en.wikipedia.org/wiki/Rounding#Rounding_half_away_from_zero Python round() method uses the "banker's rounding", which is not the behavior I want. To overcome the issue, I get the fractional part by f = abs(number - int(number)), and then use math module ceil / floor plus some conditional check to make the rounding. However, the site says it uses the same rounding algorithm in other puzzles unless explicitly specified. It would be a pain to re-implement the above method. Is there any setting we can change the default rounding behavior in Python? Or there is a built-in library can achieve the same result? The puzzle link: https://www.codeabbey.com/index/task_view/rounding

15th Jul 2024, 10:47 AM
Wong Hei Ming
Wong Hei Ming - avatar
12 Answers
+ 3
we cannot change the rounding method of the built-in rounding function... in the links, they show some examples for modules that allow for different procedures and examples on how to implement them yourself. Not sure, how many of these modules are pre-installed. https://stackoverflow.com/a/51146310 https://stackabuse.com/rounding-numbers-in-JUMP_LINK__&&__python__&&__JUMP_LINK/ https://realpython.com/python-rounding/ https://medium.com/@akhilnathe/understanding-pythons-round-function-from-basics-to-bankers-b64e7dd73477
15th Jul 2024, 11:10 AM
Lisa
Lisa - avatar
+ 3
Lisa, thanks. It seems "decimal.ROUND_HALF_UP" is what I need.
15th Jul 2024, 1:51 PM
Wong Hei Ming
Wong Hei Ming - avatar
+ 3
Bob_Li This is the method I used in the puzzle. tmp = a / b f = abs(tmp - int(tmp)) if tmp < 0: if f >= 0.5: res.append(math.floor(tmp)) else: res.append(math.ceil(tmp)) else: if f >= 0.5: res.append(math.ceil(tmp)) else: res.append(math.floor(tmp)) Your's looks better, and I haven't considered about the use of %0.5
15th Jul 2024, 2:02 PM
Wong Hei Ming
Wong Hei Ming - avatar
+ 3
Wilbur Jaywright I want the number to round up if: 1. It is a positive number; 2. The fractional is exactly 0.5 And round down if it is a negative number (orher condition unchanged). Maybe this code shows it better. https://sololearn.com/compiler-playground/cYpMlu2rKybz/?ref=app
15th Jul 2024, 2:09 PM
Wong Hei Ming
Wong Hei Ming - avatar
+ 2
Wong Hei Ming you're right. It should have been: from decimal import localcontext,Decimal,ROUND_HALF_UP def rhu(a, b): with localcontext() as ctx: ctx.rounding=ROUND_HALF_UP return (Decimal(a)/Decimal(b)).to_integral_value() print(rhu(12, 8)) print(rhu(11, -3)) print(rhu(400, 5)) #check odd/even unit, <=>±0.5 #odd unit place print(rhu(5, -4)) print(rhu(6, -4)) print(rhu(7, -4)) print(rhu(5, 4)) print(rhu(6, 4)) print(rhu(7, 4)) #even unit place print(rhu(9, -4)) print(rhu(10, -4)) print(rhu(11, -4)) print(rhu(9, 4)) print(rhu(10, 4)) print(rhu(11, 4))
16th Jul 2024, 4:14 AM
Bob_Li
Bob_Li - avatar
+ 2
Bob_Li a = Decimal('0.1') That is what b does, using f-string to create a value (0.05 + 0.05). Using f-string with Decimal would be handy if the puzzle needs to manipulate the input and the result needs rounding.
16th Jul 2024, 10:49 AM
Wong Hei Ming
Wong Hei Ming - avatar
+ 1
Bob_Li The way you create a Decimal object can lead to unexpected result. from decimal import Decimal a = Decimal(0.1) b = Decimal(f'{0.05 + 0.05}') print(a + a + a) # 0.3000000000000000166533453694 print(b + b + b) # 0.3
16th Jul 2024, 3:06 AM
Wong Hei Ming
Wong Hei Ming - avatar
+ 1
Wong Hei Ming so in your example, it should be a = Decimal(1)/Decimal(10) or a = Decimal('0.1') print(a+a+a) # 0.3
16th Jul 2024, 4:18 AM
Bob_Li
Bob_Li - avatar
0
Not sure what behavior you do want, but try combinations of int and adding or subtracting 0.5?
15th Jul 2024, 11:16 AM
Wilbur Jaywright
Wilbur Jaywright - avatar
0
Wong Hei Ming define your custom round function. %can be used for floating point numbers, so you can use it to detect 0.5, by n%0.5==0 import math def round_away(a, b): n = a/b if n>=0 and n%0.5==0: return math.ceil(n) elif n%0.5==0: return math.floor(n) else: return round(n) print(round_away(12, 8)) print(round_away(11, -3)) print(round_away(400, 5)) #check odd/even unit, <=>±0.5 #odd unit place print(round_away(5, -4)) print(round_away(6, -4)) print(round_away(7, -4)) print(round_away(5, 4)) print(round_away(6, 4)) print(round_away(7, 4)) #even unit place print(round_away(9, -4)) print(round_away(10, -4)) print(round_away(11, -4)) print(round_away(9, 4)) print(round_away(10, 4)) print(round_away(11, 4))
15th Jul 2024, 1:25 PM
Bob_Li
Bob_Li - avatar
0
Wong Hei Ming Lisa 's decimal.ROUND_HALF_UP is nice. I had to do a bit of searching on how to use it, though. from decimal import localcontext,Decimal,ROUND_HALF_UP def rhu(a, b): with localcontext() as ctx: ctx.rounding=ROUND_HALF_UP return Decimal(a/b).to_integral_value() print(rhu(12, 8)) print(rhu(11, -3)) print(rhu(400, 5)) #check odd/even unit, <=>±0.5 #odd unit place print(rhu(5, -4)) print(rhu(6, -4)) print(rhu(7, -4)) print(rhu(5, 4)) print(rhu(6, 4)) print(rhu(7, 4)) #even unit place print(rhu(9, -4)) print(rhu(10, -4)) print(rhu(11, -4)) print(rhu(9, 4)) print(rhu(10, 4)) print(rhu(11, 4))
15th Jul 2024, 11:27 PM
Bob_Li
Bob_Li - avatar
0
Wong Hei Ming No, it is not possible to directly change the default rounding method in Python's built-in round() function. If you need a specific rounding behavior, you can implement your own rounding logic using other mathematical functions in Python's math library. For example, you can achieve rounding away from zero by using a combination of abs(), int(), and conditional statements.
16th Jul 2024, 4:29 PM
MR STN
MR STN - avatar