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);
}
Ejemplo n.º 9
0
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);
}
Ejemplo n.º 16
0
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);
}
Ejemplo n.º 25
0
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());
}
Ejemplo n.º 27
0
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
}
Ejemplo n.º 28
0
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;
}
Ejemplo n.º 30
0
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
}