ROUND function working behavior question

Why 14.5 rounds down to 14 but 3.5 rounds up to 4 in the following table?
image

After using round function with 0 precision:
image

Images extracted from MySQL workbench.

I am in module three lesson 6.

The reasoning is tucked well away under the hood, and literature for Python explains it for that language, which behaves the same way. Iā€™ll leave you to search for documentation and reflect your findings in a reply. As I understand it. x.5 rounds to the nearest even integer. If x is even, it rounds down, if odd it rounds up. Perhaps your reading will find a similar explanation; looking forward to your findings.

3 Likes

According to the Python documentation at Python Docs, if the decimal point is exactly halfway between two whole numbers, the number must be rounded to the nearest even number.

However, I do not understand the following excerpt:

values are rounded to the closest multiple of 10 to the power minus ndigits

If you could explain it, it would be fantastic.

Thank you!

2 Likes

Well, I could give it a try, but it will be over the weekend as my hands are tied, for the present. Will need to ponder and get my bearings which I am presently unable to do. Please be patient and Iā€™ll get back to you. On the flip side, this is a forum so a member may pipe in before my return. Iā€™m totally open to that as I love to hear other peopleā€™s views and findings. Hereā€™s hoping you get a timely answerā€¦

1 Like

I will wait to dive in more deeply even though you answered already my outermost original question.

Thank you so much!

1 Like

round(number, ndigits=None)

ndigits is an integer provided by us to specify the digits precision of the rounding. For example round(5.55555, 1) means we want to round to one digit after the decimal. round(5.55555, 2) means we want to round to two digits after the decimal. And so on ā€¦

ā€œ10 to the power minus ndigitsā€ means:
scrn1

For Example,
round(5.55555, 1) means we want to round to the closest multiple of 1ā„ 101 (fraction form) or 0.1 (decimal form)
The multiples of 0.1 being    ..., -0.3, -0.2, -0.1, 0, 0.1, 0.2, 0.3, ..., 5.3, 5.4, 5.5, 5.6, ...
Our final answer will be one of the above numbers (the one that is closest to our value).
round(5.55555, 1) will be 5.6

round(5.55555, 2) means we want to round to the closest multiple of 1ā„ 102 (fraction form) or 0.01 (decimal form).
The multiples of 0.01 being    ..., -0.03, -0.02, -0.01, 0, 0.01, 0.02, 0.03, ..., 5.53, 5.54, 5.55, 5.56, ...
Our final answer will be one of the above numbers (the one that is closest to our value).
round(5.55555, 2) will be 5.56

So, basically the phrase tells you that when you specify ndigits, you are controlling the precision in that the final answer will not be more precise than one of the multiples.

3 Likes

How would this tie in with ā€˜significant figuresā€™, to totally derail the discussion, as a pure question, not an argument?

@mtf In theory, if you have round(5.55555, 20), my insight on multiples of 1ā„ 1020 is as follows:

..., -0.00000000000000000002, -0.00000000000000000001 , 0, 0.00000000000000000001, 0.00000000000000000002, ..., 5.55555500000000000000, 5.55556000000000000000, ...

So, round(5.55555, 20) will be 5.55556000000000000000

However, SQL dictates it finishes at the penultimate value, i.e., 5.55555500000000000000.

Does it seem right? @mtrtmk

print(round(5.55555, 20))
# 5.55555

Specifying ndigits as 20 means that we want to round to the closest multilple of    1ā„1020 (fraction form) or    0.00000000000000000001 (decimal form)

The multiples of    0.00000000000000000001     being     ..., -0.00000000000000000002, -0.00000000000000000001, 0, 0.00000000000000000001, 0.00000000000000000002, ..., 5.55555000000000000000, 5.55555000000000000001, 5.55555000000000000002, ...

To get the multiples of 0.00000000000000000001, I am just multiplying this number with integers (negative, zero, positive). There are an infinite number of negative integers and an infinite number of positive integers.

Therefore,

...
0.00000000000000000001 x 555554999999999999998 = 5.55554999999999999998
0.00000000000000000001 x 555554999999999999999 = 5.55554999999999999999
0.00000000000000000001 x 555555000000000000000 = 5.55555000000000000000
0.00000000000000000001 x 555555000000000000001 = 5.55555000000000000001
...

The final answer canā€™t be more precise (canā€™t have more decimal places) than one of the above possibilities. However, it can have less decimal places. For example. the number 5.55555 already has less than 20 digits after the decimal. So, it doesnā€™t need to be rounded.

print(round(5.55555, 20))
# 5.55555

If instead the number had say 21 or more digits after the decimal, say

print(round(5.55555555555555555555555555555, 20))
# Final answer can't have more than 20 digits after the decimal

# Expected answer:  5.55555555555555555556  

# Actual answer on my environment: 5.555555555555555 

Thatā€™s strange. The final answer has only 15 digits after the decimal, even though the original number had 20+ digits after the decimal. Also, it didnā€™t round to the nearest even. So, what is going on? You posted a link to the Python Documentation for round. In that, you will find a special note remarking that the behavior of round for floats can be surprising and it links you to an article on ā€œFloating Point Arithmeticā€. You should read that. One of the issues is that there are only so much bits that can be used for floats (depends on environment) and consequently only so many digits (usually 15 digits) after the decimal that are allowed. If you want to preserve precision, you should explore the decimal module as suggested in the article.

1 Like

I guess it would depend on what we want to accomplish. We would probably need to get a bit creative and write our own code. Most likely, others have already written such code. I am not entirely sure.

1 Like