ROUND(x,0) should leave integers alone. It does not.
I see B3=1001 [correct] and A3=1002 [wrong].
Without looking at the code I cannot be 100% certain, but the typical
cause of this trouble is that someone used
x = std::floor (x + 0.5);
thinking that such code rounds to the nearest integer. It does not.
For the value in B1 -- which is 2^52+1 -- as well as the next 2^50
odd numbers, the addition of 0.5 will actually add 1 since that is
the best approximation that fits in a double.
There is one more trouble number: the smallest number that is strictly
less than 0.5. That should round to 0, but the addition yields 1.
The solution likely is to use std::round. However, that function might
not so the desired thing for negative values.
Reproducible with LO 188.8.131.52, Win 8.1
Perhaps the calculation are beyond the precision limits.
** Please read this message in its entirety before responding **
To make sure we're focusing on the bugs that affect our users today, LibreOffice QA is asking bug reporters and confirmers to retest open, confirmed bugs which have not been touched for over a year.
There have been thousands of bug fixes and commits since anyone checked on this bug report. During that time, it's possible that the bug has been fixed, or the details of the problem have changed. We'd really appreciate your help in getting confirmation that the bug is still present.
If you have time, please do the following:
Test to see if the bug is still present on a currently supported version of LibreOffice
(5.1.6 or 5.2.3 https://www.libreoffice.org/download/
If the bug is present, please leave a comment that includes the version of LibreOffice and
your operating system, and any changes you see in the bug behavior
If the bug is NOT present, please set the bug's Status field to RESOLVED-WORKSFORME and leave
a short comment that includes your version of LibreOffice and Operating System
Please DO NOT
Update the version field
Reply via email (please reply directly on the bug tracker)
Set the bug's Status field to RESOLVED - FIXED (this status has a particular meaning that is not
appropriate in this case)
If you want to do more to help you can test to see if your issue is a REGRESSION. To do so:
1. Download and install oldest version of LibreOffice (usually 3.3 unless your bug pertains to a feature added after 3.3)
2. Test your bug
3. Leave a comment with your results.
4a. If the bug was present with 3.3 - set version to "inherited from OOo";
4b. If the bug was not present in 3.3 - add "regression" to keyword
Feel free to come ask questions or to say hello in our QA chat: http://webchat.freenode.net/?channels=libreoffice-qa
Thank you for helping us make LibreOffice even better for everyone!
Still there in 184.108.40.206. OpenLeap 42.1.
> Perhaps the calculation are beyond the precision limits.
It isn't. (And if it had been, the result would have been 1000, not 1002.)
Bug 67026 is unrelated. That one is about problems arising from 1/10 not
being exactly representable in binary. Old news.
This one is about wrong code implementing ROUND causing it to man-handle
some integers. (And that number just below 0.5 too.)
C1=1024*1024*1024*1024*1024*4 = 4503599627370496
If I'm counting well there are sixteen digits on the result.
and if I'm not wrong IEEE 754 specification it's limited to 15 digits of precision.
IEEE-758 [for binary formats] doesn't do decimal digits. It does binary
digits. C1 requires *one* binary digit of mantissa.
On page 8 of the 2008 version of the standard you will find details of
the "binary64" format that corresponds to the C "double" type on all
modern hardware. 53 bits for mantissa, 11 bits for exponent, and one
sign bit. That adds to 65 bits, but the most significant bit for the
mantissa isn't stored as it is always 1.
So C1 is perfectly representable as is B1 (=C1+1), although B1 is
just at the limit of what can be represented. But look what happens
if someone tries to round to nearest integer using this code with x=B1:
x = std::floor (x + 0.5); // WRONG
Adding 0.5 to x produces a number that is precisely midway between two
representable numbers, which are x and x+1. IEEE-758 specifies to round
according to the current rounding mode which, typically, is round-to-even. Therefore the rounding result will be x+1. std::floor will not change
that. The intent with the above code was to add 0.5 and have std::floor
throw away the decimal part. That works fine for smaller numbers, but
not for the magnitude of B1. It also works for numbers above 2*B1 because
they are all even, so adding 0.5 and rounding will leave the number
You might want to take a look at "man round", but note that it may not do
the right thing for negative numbers.
Changing A1 from =ROUND(B1,0) to =ROUND(B1,1) produces correct result (1001).
Also using either ROUNDUP(B1,0) or ROUNDDOWN(B1,0) produces a result of 1004 in A3.
All these rounding-functions use the same (rtl::math::)round() function internally.
I will look further into the code to see what exactly is happening and if it can be remedied.
It is a corner case, very close to the limit of resolution, but there is room for some improvement.
Winfried Donkers committed a patch related to this issue.
It has been pushed to "master":
tdf#96821 fix corner cases for Calc function ROUND.
It will be available in 6.1.0.
The patch should be included in the daily builds available at
http://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
Affected users are encouraged to test the fix and report feedback.