TEST(Decimal128Test, TestDecimal128GetNegInfinity) { Decimal128 d = Decimal128::kNegativeInfinity; uint64_t decimalNegativeInfinityHigh64 = 17870283321406128128ull; uint64_t decimalNegativeInfinityLow64 = 0ull; ASSERT_EQUALS(d.getValue().high64, decimalNegativeInfinityHigh64); ASSERT_EQUALS(d.getValue().low64, decimalNegativeInfinityLow64); }
TEST(Decimal128Test, TestDecimal128GetPosNaN) { Decimal128 d = Decimal128::kPositiveNaN; uint64_t decimalPositiveNaNHigh64 = 8935141660703064064ull; uint64_t decimalPositiveNaNLow64 = 0ull; ASSERT_EQUALS(d.getValue().high64, decimalPositiveNaNHigh64); ASSERT_EQUALS(d.getValue().low64, decimalPositiveNaNLow64); }
TEST(Decimal128Test, TestDecimal128GetSmallestNegative) { Decimal128 d = Decimal128::kSmallestNegative; uint64_t smallestNegativeDecimalHigh64 = 9223372036854775808ull; uint64_t smallestNegativeDecimalLow64 = 1ull; ASSERT_EQUALS(d.getValue().high64, smallestNegativeDecimalHigh64); ASSERT_EQUALS(d.getValue().low64, smallestNegativeDecimalLow64); }
TEST(Decimal128Test, TestDecimal128GetPosInfinity) { Decimal128 d = Decimal128::kPositiveInfinity; uint64_t decimalPositiveInfinityHigh64 = 8646911284551352320ull; uint64_t decimalPositiveInfinityLow64 = 0ull; ASSERT_EQUALS(d.getValue().high64, decimalPositiveInfinityHigh64); ASSERT_EQUALS(d.getValue().low64, decimalPositiveInfinityLow64); }
TEST(Decimal128Test, TestDecimal128GetSmallestPositive) { Decimal128 d = Decimal128::kSmallestPositive; uint64_t smallestPositiveDecimalHigh64 = 0ull; uint64_t smallestPositiveDecimalLow64 = 1ull; ASSERT_EQUALS(d.getValue().high64, smallestPositiveDecimalHigh64); ASSERT_EQUALS(d.getValue().low64, smallestPositiveDecimalLow64); }
TEST(Decimal128Test, TestDecimal128GetLargestNegative) { Decimal128 d = Decimal128::kLargestNegative; uint64_t largestNegativeDecimalHigh64 = 16140880215628679104ull; uint64_t largestNegativeDecimalLow64 = 4003012203950112767ull; ASSERT_EQUALS(d.getValue().high64, largestNegativeDecimalHigh64); ASSERT_EQUALS(d.getValue().low64, largestNegativeDecimalLow64); }
TEST(Decimal128Test, TestDecimal128GetLargestNegativeExponentZero) { Decimal128 d = Decimal128::kLargestNegativeExponentZero; uint64_t largestNegativeExponentZeroHigh64 = 0ull; uint64_t largestNegativeExponentZeroLow64 = 0ull; ASSERT_EQUALS(d.getValue().high64, largestNegativeExponentZeroHigh64); ASSERT_EQUALS(d.getValue().low64, largestNegativeExponentZeroLow64); }
TEST(Decimal128Test, TestDecimal128GetLargestPositive) { Decimal128 d = Decimal128::kLargestPositive; uint64_t largestPositiveDecimalHigh64 = 6917508178773903296ull; uint64_t largestPositveDecimalLow64 = 4003012203950112767ull; ASSERT_EQUALS(d.getValue().high64, largestPositiveDecimalHigh64); ASSERT_EQUALS(d.getValue().low64, largestPositveDecimalLow64); }
Decimal128 DecimalUtil::multiplyByPowerOf10(Decimal128 value, Decimal128 exponent) { Decimal128 result = value; decQuadScaleB(result.data(), value.data(), exponent.data(), getContext()); return result; }
TEST(Decimal128Test, TestDecimal128SubtractSignaling) { Decimal128 d = Decimal128::kLargestNegative; uint32_t sigFlags = Decimal128::SignalingFlag::kNoFlag; Decimal128 res = d.subtract(Decimal128(1), &sigFlags); ASSERT_TRUE(res.isEqual(Decimal128::kLargestNegative)); ASSERT_TRUE(Decimal128::hasFlag(sigFlags, Decimal128::SignalingFlag::kInexact)); }
TEST(Decimal128Test, TestDecimal128MultiplySignaling) { Decimal128 d("2"); uint32_t sigFlags = Decimal128::SignalingFlag::kNoFlag; Decimal128 res = d.multiply(Decimal128::kLargestPositive, &sigFlags); ASSERT_TRUE(res.isEqual(Decimal128::kPositiveInfinity)); ASSERT_TRUE(Decimal128::hasFlag(sigFlags, Decimal128::SignalingFlag::kOverflow)); }
TEST(Decimal128Test, TestDecimal128DivideSignaling) { Decimal128 d("2"); uint32_t sigFlags = Decimal128::SignalingFlag::kNoFlag; Decimal128 res = d.divide(Decimal128(0), &sigFlags); ASSERT_TRUE(res.isEqual(Decimal128::kPositiveInfinity)); ASSERT_TRUE(Decimal128::hasFlag(sigFlags, Decimal128::SignalingFlag::kDivideByZero)); }
Value GranularityRounderPowersOfTwo::roundDown(Value value) { uassertNonNegativeNumber(value); if (value.coerceToDouble() == 0.0) { return value; } Value exp; if (value.getType() == BSONType::NumberDouble) { exp = Value(static_cast<int>(std::ceil(std::log2(value.getDouble())) - 1.0)); } else if (value.getType() == BSONType::NumberDecimal) { Decimal128 input = value.getDecimal(); exp = Value(Decimal128( static_cast<int>((std::ceil(input.logarithm(Decimal128(2)).toDouble()) - 1.0)))); } else { long long number = value.getLong(); int leadingZeros = countLeadingZeros64(number); int trailingZeros = countTrailingZeros64(number); if (leadingZeros + trailingZeros == 63) { // If number is a power of 2, then we need to subtract an extra 1 so we round down to // the next power of 2. exp = Value(63 - leadingZeros - 1); } else { exp = Value(63 - leadingZeros); } } return ExpressionPow::create(getExpCtx(), Value(2), exp)->evaluate(Document()); }
TEST(Decimal128Test, TestDecimal128GetNegNaN) { Decimal128 d = Decimal128::kNegativeNaN; uint64_t decimalNegativeNaNHigh64 = 18158513697557839872ull; uint64_t decimalNegativeNaNLow64 = 0ull; ASSERT_EQUALS(d.getValue().high64, decimalNegativeNaNHigh64); ASSERT_EQUALS(d.getValue().low64, decimalNegativeNaNLow64); }
TEST(Decimal128Test, TestDecimal128Quantize) { Decimal128 expected("1.00001"); Decimal128 val("1.000008"); Decimal128 ref("0.00001"); Decimal128 result = val.quantize(ref); ASSERT_EQUALS(result.getValue().low64, expected.getValue().low64); ASSERT_EQUALS(result.getValue().high64, expected.getValue().high64); }
void NumberDecimalInfo::Functions::toString::call(JSContext* cx, JS::CallArgs args) { Decimal128 val = NumberDecimalInfo::ToNumberDecimal(cx, args.thisv()); str::stream ss; ss << "NumberDecimal(\"" << val.toString() << "\")"; ValueReader(cx, args.rval()).fromStringData(ss.operator std::string()); }
TEST(Decimal128Test, TestDecimal128DivisionCase2) { Decimal128 d1("1.00"); Decimal128 d2("2.000"); Decimal128 result = d1.divide(d2); Decimal128 expected("0.5"); ASSERT_EQUALS(result.getValue().low64, expected.getValue().low64); ASSERT_EQUALS(result.getValue().high64, expected.getValue().high64); }
TEST(Decimal128Test, TestDecimal128MultiplicationCase2) { Decimal128 d1("1.00"); Decimal128 d2("2.000"); Decimal128 result = d1.multiply(d2); Decimal128 expected("2.00000"); ASSERT_EQUALS(result.getValue().low64, expected.getValue().low64); ASSERT_EQUALS(result.getValue().high64, expected.getValue().high64); }
TEST(Decimal128Test, TestDecimal128DivisionCase1) { Decimal128 d1("25.05E20"); Decimal128 d2("-50.5218E19"); Decimal128 result = d1.divide(d2); Decimal128 expected("-4.958255644098191275845278671781290"); ASSERT_EQUALS(result.getValue().low64, expected.getValue().low64); ASSERT_EQUALS(result.getValue().high64, expected.getValue().high64); }
TEST(Decimal128Test, TestDecimal128SubtractionCase2) { Decimal128 d1("1.00"); Decimal128 d2("2.000"); Decimal128 result = d1.subtract(d2); Decimal128 expected("-1.000"); ASSERT_EQUALS(result.getValue().low64, expected.getValue().low64); ASSERT_EQUALS(result.getValue().high64, expected.getValue().high64); }
TEST(Decimal128Test, TestDecimal128MultiplicationCase1) { Decimal128 d1("25.05E20"); Decimal128 d2("-50.5218E19"); Decimal128 result = d1.multiply(d2); Decimal128 expected("-1.265571090E42"); ASSERT_EQUALS(result.getValue().low64, expected.getValue().low64); ASSERT_EQUALS(result.getValue().high64, expected.getValue().high64); }
TEST(Decimal128Test, TestDecimal128AdditionCase2) { Decimal128 d1("1.00"); Decimal128 d2("2.000"); Decimal128 result = d1.add(d2); Decimal128 expected("3.000"); ASSERT_EQUALS(result.getValue().low64, expected.getValue().low64); ASSERT_EQUALS(result.getValue().high64, expected.getValue().high64); }
TEST(Decimal128Test, TestDecimal128SubtractionCase1) { Decimal128 d1("25.05E20"); Decimal128 d2("-50.5218E19"); Decimal128 result = d1.subtract(d2); Decimal128 expected("3.010218E21"); ASSERT_EQUALS(result.getValue().low64, expected.getValue().low64); ASSERT_EQUALS(result.getValue().high64, expected.getValue().high64); }
// Tests for Decimal128 math operations TEST(Decimal128Test, TestDecimal128AdditionCase1) { Decimal128 d1("25.05E20"); Decimal128 d2("-50.5218E19"); Decimal128 result = d1.add(d2); Decimal128 expected("1.999782E21"); ASSERT_EQUALS(result.getValue().low64, expected.getValue().low64); ASSERT_EQUALS(result.getValue().high64, expected.getValue().high64); }
int DecimalUtil::classify(Decimal128 x) { #if BDLDFP_DECIMALPLATFORM_C99_TR return fpclassify(x.value()); #elif BDLDFP_DECIMALPLATFORM_DECNUMBER enum decClass cl = decQuadClass(x.data()); return deClass2FP_(cl); #endif }
InternalSchemaFmodMatchExpression::InternalSchemaFmodMatchExpression(StringData path, Decimal128 divisor, Decimal128 remainder) : LeafMatchExpression(MatchType::INTERNAL_SCHEMA_FMOD, path), _divisor(divisor), _remainder(remainder) { uassert(ErrorCodes::BadValue, "divisor cannot be 0", !divisor.isZero()); uassert(ErrorCodes::BadValue, "divisor cannot be NaN", !divisor.isNaN()); uassert(ErrorCodes::BadValue, "divisor cannot be infinite", !divisor.isInfinite()); }
Decimal128 DecimalUtil::fabs(Decimal128 value) { #if BDLDFP_DECIMALPLATFORM_C99_TR return fabsd128(value.value()); #elif BDLDFP_DECIMALPLATFORM_DECNUMBER Decimal128 rv; decQuadAbs(rv.data(), value.data(), getContext()); return rv; #endif }
Decimal128 DecimalUtil::multiplyByPowerOf10(Decimal128 value, int exponent) { BSLS_ASSERT(-1999999997 <= exponent); BSLS_ASSERT( exponent <= 99999999); Decimal128 result = value; DecimalImplUtil::ValueType128 scale = DecimalImplUtil::makeDecimalRaw128(exponent, 0); decQuadScaleB(result.data(), value.data(), &scale, getContext()); return result; }
bool InternalSchemaFmodMatchExpression::matchesSingleElement(const BSONElement& e, MatchDetails* details) const { if (!e.isNumber()) { return false; } std::uint32_t flags = Decimal128::SignalingFlag::kNoFlag; Decimal128 result = e.numberDecimal().modulo(_divisor, &flags); if (flags == Decimal128::SignalingFlag::kNoFlag) { return result.isEqual(_remainder); } return false; }
Decimal128 DecimalUtil::round(Decimal128 x) { #if BDLDFP_DECIMALPLATFORM_C99_TR return roundd128(x.value()); #elif BDLDFP_DECIMALPLATFORM_DECNUMBER Decimal128 rv; decQuadToIntegralValue(rv.data(), x.data(), getContext(), DEC_ROUND_HALF_UP); return rv; #endif }