diff options
author | Denis Grebennicov <denis.grebennicov@mongodb.com> | 2022-08-17 17:24:20 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-10-06 16:59:29 +0000 |
commit | 26350ca57b016f0fa755d4cd8034bf5e491242b2 (patch) | |
tree | e4bea30cfae2ce65dd932ccb312e18a381a3956c | |
parent | 19912e29a71943349ce86066166cfd7fc14ea79d (diff) | |
download | mongo-26350ca57b016f0fa755d4cd8034bf5e491242b2.tar.gz |
SERVER-68233 MongoShell numberDecimalsAlmostEqual(NumberDecimal(0), NumberDecimal(0)) returns false
-rw-r--r-- | jstests/decimal/decimal_constructors.js | 45 | ||||
-rw-r--r-- | src/mongo/shell/shell_utils.cpp | 22 |
2 files changed, 44 insertions, 23 deletions
diff --git a/jstests/decimal/decimal_constructors.js b/jstests/decimal/decimal_constructors.js index c4611385b8a..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"), @@ -87,4 +87,17 @@ assert(numberDecimalsAlmostEqual(NumberDecimal("-104735446372966662851.013527641 10)); // Regression test for BF-25390 assert(numberDecimalsAlmostEqual(NumberDecimal("-331.0000000000"), NumberDecimal("-331"), 10)); + +// Verify numberDecimalsAlmostEqual() works with 0. +assert(numberDecimalsAlmostEqual(NumberDecimal("0"), NumberDecimal("0"), 10)); +assert(numberDecimalsAlmostEqual(NumberDecimal("0"), NumberDecimal("0.0000000000000001"), 10)); +assert(numberDecimalsAlmostEqual(NumberDecimal("0.0000000000000001"), NumberDecimal("0"), 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 cb82f223f9b..abdbb179bfa 100644 --- a/src/mongo/shell/shell_utils.cpp +++ b/src/mongo/shell/shell_utils.cpp @@ -521,14 +521,22 @@ BSONObj numberDecimalsAlmostEqual(const BSONObj& input, void*) { auto ten = Decimal128(10); auto exponent = a.toAbs().logarithm(ten).round(); - // Return early if arguments are not the same order of magnitude. - if (exponent != b.toAbs().logarithm(ten).round()) { - return BSON("" << false); - } + // 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. + if (exponent != b.toAbs().logarithm(ten).round()) { + return BSON("" << false); + } - // Put the whole number behind the decimal point. - a = a.divide(ten.power(exponent)); - b = b.divide(ten.power(exponent)); + // Put the whole number behind the decimal point. + if (!exponent.isZero()) { + a = a.divide(ten.power(exponent)); + b = b.divide(ten.power(exponent)); + } + } auto places = third.numberDecimal(); auto isErrorAcceptable = a.subtract(b) |