Translate Rounding like a banker example

This commit is contained in:
Vadim Nifadev 2024-04-23 12:18:36 +03:00
parent a25fe26adc
commit 0d28d47f08

View File

@ -2517,3 +2517,55 @@ class SomeClass:
- Начиная с версии Python 3.X, списковые вычисления также имеют свою собственную область видимости.
---
### ▶ Округляясь как банкир *
Реализуем простейшую функцию по получению среднего элемента списка:
```py
def get_middle(some_list):
mid_index = round(len(some_list) / 2)
return some_list[mid_index - 1]
```
**Python 3.x:**
```py
>>> get_middle([1]) # вроде неплохо
1
>>> get_middle([1,2,3]) # все еще хорошо
2
>>> get_middle([1,2,3,4,5]) # что-то не то?
2
>>> len([1,2,3,4,5]) / 2 # хорошо
2.5
>>> round(len([1,2,3,4,5]) / 2) # почему снова так?
2
```
Кажется, Python округлил 2.5 до 2.
#### 💡 Объяснение:
- Это не ошибка округления float, на самом деле такое поведение намеренно. Начиная с Python 3.0, `round()` использует [округление банкира](https://en.wikipedia.org/wiki/Rounding#Round_half_to_even), где дроби .5 округляются до ближайшего **четного** числа.
```py
>>> round(0.5)
0
>>> round(1.5)
2
>>> round(2.5)
2
>>> import numpy # поведение numpy аналогично
>>> numpy.round(0.5)
0.0
>>> numpy.round(1.5)
2.0
>>> numpy.round(2.5)
2.0
```
- Это рекомендуемый способ округления дробей до .5, описанный в [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754#Rounding_rules). Однако в школах чаще всего преподают другой способ (округление от нуля), поэтому округление банкира, скорее всего, не так хорошо известно. Более того, некоторые из самых популярных языков программирования (например, JavaScript, Java, C/C++, Ruby, Rust) также не используют округление банкира. Таким образом, для Python это все еще довольно специфично и может привести к путанице при округлении дробей.
- Дополнительную информацию можно найти в [документации](https://docs.python.org/3/library/functions.html#round) функции `round` или на [StackOverflow](https://stackoverflow.com/questions/10825926/python-3-x-rounding-behavior).
---