Why 14.5 rounds down to 14 but 3.5 rounds up to 4 in the following table?
After using round function with 0 precision:
Images extracted from MySQL workbench.
Why 14.5 rounds down to 14 but 3.5 rounds up to 4 in the following table?
After using round function with 0 precision:
Images extracted from MySQL workbench.
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.
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!
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ā¦
I will wait to dive in more deeply even though you answered already my outermost original question.
Thank you so much!
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:
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.
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.
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.