summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Grebennicov <denis.grebennicov@mongodb.com>2022-08-22 07:59:11 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-08-22 08:30:19 +0000
commit02276ba2c720ae0060224df0348e08c31be764d5 (patch)
treed21ce28f485e3dd8fd2141dfa1af0bacb05e007e
parentc3058c49b899ddafbbe17dff9ab9a64b9346e29f (diff)
downloadmongo-02276ba2c720ae0060224df0348e08c31be764d5.tar.gz
SERVER-68233 MongoShell numberDecimalsAlmostEqual(NumberDecimal(0), NumberDecimal(0)) returns false
-rw-r--r--jstests/decimal/decimal_constructors.js41
-rw-r--r--src/mongo/shell/shell_utils.cpp10
2 files changed, 31 insertions, 20 deletions
diff --git a/jstests/decimal/decimal_constructors.js b/jstests/decimal/decimal_constructors.js
index bebbc6e3d94..0d3ff990f7b 100644
--- a/jstests/decimal/decimal_constructors.js
+++ b/jstests/decimal/decimal_constructors.js
@@ -50,36 +50,36 @@ assert.throws(() => numberDecimalsEqual(NumberDecimal('10.20'), "Wrong parameter
// Verify the behavior of 'numberDecimalsAlmostEqual' helper.
assert(numberDecimalsAlmostEqual(NumberDecimal("10001"), NumberDecimal("10002"), 3));
-assert.neq(numberDecimalsAlmostEqual(NumberDecimal("10001"), NumberDecimal("10002"), 5));
+assert(!numberDecimalsAlmostEqual(NumberDecimal("10001"), NumberDecimal("10002"), 5));
// Regression tests for BF-24149.
assert(numberDecimalsAlmostEqual(NumberDecimal("905721242210.0455427920454969568"),
NumberDecimal("905721242210.0453137831269007622941"),
15));
-assert.neq(numberDecimalsAlmostEqual(NumberDecimal("905721242210.0455427920454969568"),
- NumberDecimal("905721242210.0453137831269007622941"),
- 16));
+assert(!numberDecimalsAlmostEqual(NumberDecimal("905721242210.0455427920454969568"),
+ NumberDecimal("905721242210.0453137831269007622941"),
+ 16));
// Verify helper works the same with negative numers.
assert(numberDecimalsAlmostEqual(NumberDecimal("-10001"), NumberDecimal("-10002"), 3));
-assert.neq(numberDecimalsAlmostEqual(NumberDecimal("-10001"), NumberDecimal("-10002"), 5));
+assert(!numberDecimalsAlmostEqual(NumberDecimal("-10001"), NumberDecimal("-10002"), 5));
assert(numberDecimalsAlmostEqual(NumberDecimal("-905721242210.0455427920454969568"),
NumberDecimal("-905721242210.0453137831269007622941"),
15));
-assert.neq(numberDecimalsAlmostEqual(NumberDecimal("-905721242210.0455427920454969568"),
- NumberDecimal("-905721242210.0453137831269007622941"),
- 16));
+assert(!numberDecimalsAlmostEqual(NumberDecimal("-905721242210.0455427920454969568"),
+ NumberDecimal("-905721242210.0453137831269007622941"),
+ 16));
// Verify mixed-sign arguments aren't equal.
-assert.neq(numberDecimalsAlmostEqual(NumberDecimal("10001"), NumberDecimal("-10002"), 3));
-assert.neq(numberDecimalsAlmostEqual(NumberDecimal("-10001"), NumberDecimal("10002"), 3));
-assert.neq(numberDecimalsAlmostEqual(NumberDecimal("-905721242210.0455427920454969568"),
- NumberDecimal("905721242210.0453137831269007622941"),
- 10));
-assert.neq(numberDecimalsAlmostEqual(NumberDecimal("905721242210.0455427920454969568"),
- NumberDecimal("-905721242210.0453137831269007622941"),
- 10));
+assert(!numberDecimalsAlmostEqual(NumberDecimal("10001"), NumberDecimal("-10002"), 3));
+assert(!numberDecimalsAlmostEqual(NumberDecimal("-10001"), NumberDecimal("10002"), 3));
+assert(!numberDecimalsAlmostEqual(NumberDecimal("-905721242210.0455427920454969568"),
+ NumberDecimal("905721242210.0453137831269007622941"),
+ 10));
+assert(!numberDecimalsAlmostEqual(NumberDecimal("905721242210.0455427920454969568"),
+ NumberDecimal("-905721242210.0453137831269007622941"),
+ 10));
// Regression test for BF-25335
assert(numberDecimalsAlmostEqual(NumberDecimal("-104735446372966662851.0135276410897"),
@@ -92,5 +92,12 @@ assert(numberDecimalsAlmostEqual(NumberDecimal("-331.0000000000"), NumberDecimal
assert(numberDecimalsAlmostEqual(NumberDecimal("0"), NumberDecimal("0"), 10));
assert(numberDecimalsAlmostEqual(NumberDecimal("0"), NumberDecimal("0.0000000000000001"), 10));
assert(numberDecimalsAlmostEqual(NumberDecimal("0.0000000000000001"), NumberDecimal("0"), 10));
-assert.neq(numberDecimalsAlmostEqual(NumberDecimal("0"), NumberDecimal("0.000001"), 10));
+assert(!numberDecimalsAlmostEqual(NumberDecimal("1.00000000000000"), NumberDecimal("1.1"), 10));
+assert(numberDecimalsAlmostEqual(
+ NumberDecimal("1.00000000000000"), NumberDecimal("1.00000000000001"), 10));
+assert(numberDecimalsAlmostEqual(NumberDecimal("Infinity"), NumberDecimal("Infinity"), 10));
+assert(!numberDecimalsAlmostEqual(NumberDecimal("Infinity"), NumberDecimal("-Infinity"), 10));
+assert(!numberDecimalsAlmostEqual(NumberDecimal("Infinity"), NumberDecimal("NaN"), 10));
+assert(numberDecimalsAlmostEqual(NumberDecimal("NaN"), NumberDecimal("NaN"), 10));
+assert(!numberDecimalsAlmostEqual(NumberDecimal("0"), NumberDecimal("0.000001"), 10));
}());
diff --git a/src/mongo/shell/shell_utils.cpp b/src/mongo/shell/shell_utils.cpp
index 47baffad750..dc8ffcd113e 100644
--- a/src/mongo/shell/shell_utils.cpp
+++ b/src/mongo/shell/shell_utils.cpp
@@ -529,7 +529,9 @@ BSONObj numberDecimalsAlmostEqual(const BSONObj& input, void*) {
auto ten = Decimal128(10);
auto exponent = a.toAbs().logarithm(ten).round();
- if (a.isZero() && b.isZero()) {
+ // Early exit for zero, infinity and NaN cases.
+ if ((a.isZero() && b.isZero()) || (a.isNaN() && b.isNaN()) ||
+ (a.isInfinite() && b.isInfinite() && (a.isNegative() == b.isNegative()))) {
return BSON("" << true /* isErrorAcceptable */);
} else if (!a.isZero() && !b.isZero()) {
// Return early if arguments are not the same order of magnitude.
@@ -538,8 +540,10 @@ BSONObj numberDecimalsAlmostEqual(const BSONObj& input, void*) {
}
// Put the whole number behind the decimal point.
- a = a.divide(ten.power(exponent));
- b = b.divide(ten.power(exponent));
+ if (!exponent.isZero()) {
+ a = a.divide(ten.power(exponent));
+ b = b.divide(ten.power(exponent));
+ }
}
auto places = third.numberDecimal();