[SERVER-56593] Unexpected tie-breaking behavior in DoubleDoubleSummation::getLong() Created: 03/May/21  Updated: 06/Dec/22

Status: Backlog
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Justin Seyster Assignee: Backlog - Storage Execution Team
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to SERVER-56284 SBE $add with Date and NumberDecimal ... Closed
Assigned Teams:
Storage Execution
Operating System: ALL
Sprint: Execution Team 2021-06-28, Execution Team 2021-07-12, Execution Team 2021-07-26, Execution Team 2021-08-09, Execution Team 2021-08-23, Execution Team 2021-09-06, Execution Team 2021-09-20, Execution Team 2021-10-04, Execution Team 2021-10-18, Execution Team 2021-11-01, Execution Team 2021-11-15, Execution Team 2021-11-29, Execution Team 2021-12-13, Execution Team 2021-12-27, Execution Team 2022-01-10, Execution Team 2022-01-24, Execution Team 2022-02-07, Execution Team 2022-02-21, Execution Team 2022-03-07, Execution Team 2022-03-21, Execution Team 2022-04-04, Execution Team 2022-04-18, Execution Team 2022-05-02, Execution Team 2022-05-16
Participants:

 Description   

By plugging values into DoubleDoubleSummation and calling getLong(), I've observed that it rounds non-integer values to the nearest integer (e.g., 4.6 rounds up to 5) but with strange tie-breaking behavior. All the values I've tested that end in .5 (nearest integer is a tie) round towards 0. For example, 2.5 becomes 2.

The most common tie-breaking modes round ties away from 0 (2.5 would become 3) or round ties toward the nearest even integer. The current behavior isn't necessarily wrong, but it is unconventional.

I wrote a short unit test to illustrate. Note that this test case passes on my local machine.

diff --git a/src/mongo/util/summation_test.cpp b/src/mongo/util/summation_test.cpp
index c04e6b933f..c18217d055 100644
--- a/src/mongo/util/summation_test.cpp
+++ b/src/mongo/util/summation_test.cpp
@@ -232,4 +232,38 @@ TEST(Summation, ConvertNaNToDecimal) {
     ASSERT_TRUE(sum.getDecimal().isNaN());
     ASSERT_FALSE(sum.getDecimal().isInfinite());
 }
+
+TEST(Summation, RoundingDoubleToLong) {
+    {
+        DoubleDoubleSummation sum;
+        sum.addLong(2);
+        sum.addDouble(0.499);
+        // Rounds towards nearest integer.
+        ASSERT_EQ(sum.getLong(), 2);
+    }
+
+    {
+        DoubleDoubleSummation sum;
+        sum.addLong(2);
+        sum.addDouble(0.501);
+        // Rounds towards nearest integer.
+        ASSERT_EQ(sum.getLong(), 3);
+    }
+
+    {
+        DoubleDoubleSummation sum;
+        sum.addLong(2);
+        sum.addDouble(0.5);
+        // Breaks tie _toward_ 0.
+        ASSERT_EQ(sum.getLong(), 2);
+    }
+
+    {
+        DoubleDoubleSummation sum;
+        sum.addLong(-2);
+        sum.addDouble(-0.5);
+        // Breaks tie _toward_ 0.
+        ASSERT_EQ(sum.getLong(), -2);
+    }
+}
 }  // namespace mongo



 Comments   
Comment by Justin Seyster [ 03/May/21 ]

DoubleDoubleSummation:toLong() affects $add when one of the operands is a date. MQL converts the result of the addition to an int64_t value (representing ms since the epoch). I observed this issue while trying to get the behavior of a $add in SBE to closely match the behavior in the existing version.

Generated at Thu Feb 08 05:39:41 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.