<jupyter_start><jupyter_text>Rounding in PythonRay BuhrOct. 30, 2019 In elementary school, we learned how to round decimals. For example, we learned that:- `10.5` rounds to `11`- `15.5` rounds to `16`<jupyter_code>print(f"10.5 rounds to 11, but in python it rounds to {round(10.5)}")

print(f"15.5 rounds to 16, and in python it rounds to {round(15.5)}")<jupyter_output>10.5 rounds to 11, but in python it rounds to 10
15.5 rounds to 16, and in python it rounds to 16<jupyter_text>![not sure if](https://i.kym-cdn.com/entries/icons/original/000/006/026/NOTSUREIF.jpg)  What just happened?We noticed that `15.5` _rounded up_ to `16` like we expected, but for some reason `10.5` did not _round up_ to `11`. Instead `10.5` _rounded down_ to `10`. Let's test out a few more cases to see what's going on here.<jupyter_code>numbers = [i + 0.5 for i in range(-50, 50)]
print("some numbers", numbers[20::7], sep="\n")

rounded_numbers = [round(num) for num in numbers]
print("\nthose same numbers rounded", rounded_numbers[20::7], sep="\n")<jupyter_output>some numbers
[-29.5, -22.5, -15.5, -8.5, -1.5, 5.5, 12.5, 19.5, 26.5, 33.5, 40.5, 47.5]

those same numbers rounded
[-30, -22, -16, -8, -2, 6, 12, 20, 26, 34, 40, 48]<jupyter_text>Did you notice the pattern?All the numbers whose integer component was **even _rounded down_**while the numbers whose integer component was **odd _rounded up_**This is called **_even rounding_**>This is the default rounding mode used in IEEE 754 floating-point operations ![rounding algos](Comparison_rounding_graph.png)  So why does this matter?<jupyter_code>import numpy as np

numbers = (
    np.random.randint(low=-100, high=100, size=100_000) + 
    np.random.random(100_000).round(2)
)

print("Sum of numpy array:", numbers.round().sum())

from decimal import Decimal, ROUND_HALF_UP

decimals = [Decimal(n) for n in numbers]
print(
    "Sum of decimal array:",
    sum(d.quantize(0, rounding=ROUND_HALF_UP) for d in decimals)
)<jupyter_output>Sum of numpy array: -6549.0
Sum of decimal array: -6530
{'fraction_non_alphanumeric': 0.13533464566929135, 'fraction_numerical': 0.08267716535433071, 'mean_word_length': 4.616022099447513, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 11, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '122995', 'license': 'MIT', 'n_tokens_mistral': 835, 'n_tokens_neox': 712, 'n_words': 256, 'path': 'rounding-in-python/rounding_in_python.ipynb', 'repo_name': 'raybuhr/talks', 'size': '2032'}