- changed milestone to 0.12
round(0.5) returns 0
SpeedCrunch master-a091763c26002bc3fa4597c98ca8f1c229f3dde7 (Portable Edition) (Qt 5.5.0), Windows 7 64-bit.
round(0.5) returns 0. round(1/2) returns 0.
I believe it must be 1.
Comments (26)
-
-
This comes from
floatcommon.c
, line 367:if (digit < 5 || (digit == 5 && float_getlength(x) == 1)) value = 0;
I have no idea what this second condition is good for. Someone must have been thinking something.
-
AFAICT, it literally says: if the number is 0.5, round down. Weird.
This also happens when doing
round(0.05; 1)
or similar. -
This condition has always been around in the "new" math engine (as in, introduced in bb03ae3f8df408 back in 2007). There's a justification in doc/legacy/new_engine.pdf, at the bottom of page 2:
Second, 0.5, rounded to an integer, yields 0, not 1. This is conforming to international rounding rules, that say, if the cut off digit is a single 5 only, rounding occurs such that the last digit of the rounded result is even. This eliminates a slight bias against rounding down, that otherwise would be present. (Note: according to this rule, 1.5 is rounded to 2).
I haven't heard of that special case before, but that doesn't really mean anything. Still, it seems odd to me as well.
-
repo owner I guess this is what the description refers to:
This is the default rounding mode used in IEEE 754 computing functions and operators (see also Nearest integer function).
-
repo owner What concerns me the most is the fact that we don't have a single test for this situation. I checked testfloatnum, testevaluator and testhmath. I'm honestly not sure which rounding method we should provide, but whichever it is, we should thoroughly document it.
-
Oh... this 'Round half to even' thing makes sense. We should test and document this. Thanks for digging this up!
-
- changed status to resolved
Fixes issue #636
→ <<cset bcd6782b3f6e>>
-
Are there mistype(s) in the corresponding examples and unit tests? Taking into account that only round(0.5) results in rounding to 0, I can't understand the following below:
+ round(12.345; 2) + = 12.34 // shoudn't it be "12.35" ?
And, anyway, doesn't such idea of rounding contradict with classical mathematics?
And the following 1 line below:
+ CHECK(HMath::round("0.5", 0), "0"); // OK (0.5 is rounded to 0) + CHECK(HMath::round("1.5", 0), "2"); // OK + CHECK(HMath::round("2.5", 0), "2"); // "2" ??? Shoudn't it be "3" ? + CHECK(HMath::round("3.5", 0), "4"); // OK + CHECK(HMath::round("-0.5", 0), "0"); // OK (-0.5 is rounded to -0) + CHECK(HMath::round("-1.5", 0), "-2"); // OK
-
@DV__ please read that part of the Wikipedia article. Basically, when there is a tie, it rounds to the nearest even integer.
For the record, this is how the rounding in the C standard library
printf()
function behaves but not howround()
from the same library does. -
My opinion: those people are mad. Mathematics used to be exact science - but with these "rounding adjustments" it's not. Let's say you want to calculate: 1. round(0.5) + round(2.5) + round(4.5) 2. round(1.5) + round(3.5) + round(5.5) With "classical" mathematics, you always get the exact results: 1. 9 2. 12 With the proposed "adjustments", you can get: 1. 6 or 9 2. 9 or 12 In terms of exact science, it's inadmissible!
-
Rounding will always introduce an error, in particular when summing. Naturally you can always find a sequence where any strategy performs particularly poorly.
The 'round to even' strategy minimizes bias for any sane distribution.
Also, if you are rounding at all, things stop being an exact science by definition. ;)
Finally I'd like to point out that if you really care about the error introduced by tie breaking rules, then you are rounding too much :)
TL;DR: Let's leave SC the way it is.
-
About your example: the 'exact' result is the one without any rounding at all. A highly desirable characteristic of a rounding operation is to preserve e.g. a sum. This is done much better by rounding to even. Your example perfectly illustrates this.
-
My last comments. Maybe it could be an option? Because: 1) I don't see strong arguments why one would prefer rounding to odd to rounding to even; 2) in any case, this will blow someone's mind when rounding numbers with .5 at the end gives different results.
Let's look at Python:
>>> map(lambda x: round(x), (0.5, 1.5, 2.5, 3.5, 4.5)) [1.0, 2.0, 3.0, 4.0, 5.0]
So it uses a "classical" rule. IMHO, a simple mathematical engine by default should not deal with "banking rounding" and similar. Just because it's unexpected.
-
repo owner I can honestly see both points here. SpeedCrunch tries to be SI-compliant, mathematically correct, and all that jazz. But myself had never heard of round-to-even before I found that Wikipedia page motivated by the reporting of this issue by Vitalii. I can see how confused the average user can become because of the default behavior we provide. l'd say we should modify
round()
by adding support to 3 or 4 rounding stategies (the default being the one Vitalii and most users would expect). The the behavior would happen according to the radio group option selected somewhere in the Settings menu. An alternative is to offerroundzero()
,roundinf()
,round()
(alias forroundinf()
),roundeven()
androundodd()
-
I'm fine with any approach. The whole debate is indeed rather silly.
FYI, in Matlab,
round()
rounds ties away from zero, whileconvergent()
does the even thing.To be honest, I don't see the need to add more than one function, and definitely not another setting. I still think that if you are rounding to the point where this matters, you are rounding too much. Really, anyone algorithm is fine for me. I was just trying to motivate the round-to-even way :)
-
I don't have any strong opinion either; that being said, rounding to infinity is probably the behaviour most people expect (it's certainly what I expected as well), I think we should switch to that (and explicitly document it). We can revisit the question of extra functions or a setting later IMO.
(I do think a setting would be better because it would also control what rounding you get when using an explicit decimal precision setting.)
-
I also like the user setting proposal with the default set to round tie to infinity or zero, but not to even or odd (these rounding logic do not sound natural to me, even though I understand why they exist now).
Speaking of user settings, since the settings menu is getting more and more populated, is there a plan to put them in a settings dialog some day?
-
repo owner is there a plan to put them in a settings dialog some day?
You read my mind.
-
This was automatically closed when I submitted my PR. Shall I reopen this and kill the PR?
-
repo owner - changed status to open
-
repo owner - changed status to resolved
Fixes issue #636
→ <<cset bcd6782b3f6e>>
-
repo owner -
repo owner - changed status to open
-
repo owner -
Issue
#983was marked as a duplicate of this issue. - Log in to comment