ROUND(x,0) should leave integers alone. It does not. A1=ROUND(B1,0) B1=C1+1 C1=1024*1024*1024*1024*1024*4 A3=A1-(C1-1000) B3=B1-(C1-1000) 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 5.1.0.1, 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) http://downloadarchive.documentfoundation.org/libreoffice/old/ 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! Warm Regards, QA Team MassPing-UntouchedBug-20170103
Still there in 5.2.3.3. 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.)
https://bugs.documentfoundation.org/show_bug.cgi?id=67026
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. https://lists.freedesktop.org/archives/libreoffice-bugs/2014-August/215620.html https://support.microsoft.com/en-us/kb/78113
C1=1024*1024*1024*1024*1024*4 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 unchanged. 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": http://cgit.freedesktop.org/libreoffice/core/commit/?id=b97a0df0f3234b4c1140ba1418d4b96a592afa4a 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: http://wiki.documentfoundation.org/Testing_Daily_Builds Affected users are encouraged to test the fix and report feedback.