mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-22 04:59:34 +01:00
Revert "SERVER-24374 Make Decimal128 integer ctors constexpr"
This reverts commit e039271638
.
This commit is contained in:
parent
e039271638
commit
58df54d9c7
@ -147,12 +147,12 @@ env.Library(
|
||||
'$BUILD_DIR/third_party/shim_allocator',
|
||||
'$BUILD_DIR/third_party/shim_boost',
|
||||
'$BUILD_DIR/third_party/shim_fmt',
|
||||
'$BUILD_DIR/third_party/shim_intel_decimal128',
|
||||
'$BUILD_DIR/third_party/shim_pcrecpp',
|
||||
'boost_assert_shim',
|
||||
'util/quick_exit',
|
||||
],
|
||||
LIBDEPS_PRIVATE=[
|
||||
'$BUILD_DIR/third_party/shim_intel_decimal128',
|
||||
'util/debugger',
|
||||
],
|
||||
)
|
||||
|
@ -187,6 +187,15 @@ BID_UINT128 decimal128ToLibraryType(Decimal128::Value value) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Decimal128::Decimal128(std::int32_t int32Value)
|
||||
: _value(libraryTypeToValue(bid128_from_int32(int32Value))) {}
|
||||
|
||||
Decimal128::Decimal128(std::int64_t int64Value)
|
||||
: _value(libraryTypeToValue(bid128_from_int64(int64Value))) {}
|
||||
|
||||
Decimal128::Decimal128(std::uint64_t uint64Value)
|
||||
: _value(libraryTypeToValue(bid128_from_uint64(uint64Value))) {}
|
||||
|
||||
/**
|
||||
* Quantize a doubleValue argument to a Decimal128 with exactly 15 digits
|
||||
* of precision.
|
||||
@ -283,8 +292,8 @@ Decimal128::Decimal128(double doubleValue,
|
||||
|
||||
// Check if the quantization was done correctly: _value stores exactly 15
|
||||
// decimal digits of precision (15 digits can fit into the low 64 bits of the decimal)
|
||||
std::uint64_t kSmallest15DigitInt = 1E14; // A 1 with 14 zeros
|
||||
std::uint64_t kLargest15DigitInt = 1E15 - 1; // 15 nines
|
||||
uint64_t kSmallest15DigitInt = 1E14; // A 1 with 14 zeros
|
||||
uint64_t kLargest15DigitInt = 1E15 - 1; // 15 nines
|
||||
if (getCoefficientLow() > kLargest15DigitInt) {
|
||||
// If we didn't precisely get 15 digits of precision, the original base 10 exponent
|
||||
// guess was 1 off, so quantize once more with base10Exp + 1
|
||||
@ -315,6 +324,10 @@ Decimal128::Decimal128(std::string stringValue,
|
||||
_value = libraryTypeToValue(dec128);
|
||||
}
|
||||
|
||||
Decimal128::Value Decimal128::getValue() const {
|
||||
return _value;
|
||||
}
|
||||
|
||||
Decimal128 Decimal128::toAbs() const {
|
||||
BID_UINT128 dec128 = decimal128ToLibraryType(_value);
|
||||
dec128 = bid128_abs(dec128);
|
||||
@ -448,12 +461,12 @@ std::int32_t Decimal128::toInt(std::uint32_t* signalingFlags, RoundingMode round
|
||||
}
|
||||
}
|
||||
|
||||
std::int64_t Decimal128::toLong(RoundingMode roundMode) const {
|
||||
int64_t Decimal128::toLong(RoundingMode roundMode) const {
|
||||
std::uint32_t throwAwayFlag = 0;
|
||||
return toLong(&throwAwayFlag, roundMode);
|
||||
}
|
||||
|
||||
std::int64_t Decimal128::toLong(std::uint32_t* signalingFlags, RoundingMode roundMode) const {
|
||||
int64_t Decimal128::toLong(std::uint32_t* signalingFlags, RoundingMode roundMode) const {
|
||||
BID_UINT128 dec128 = decimal128ToLibraryType(_value);
|
||||
switch (roundMode) {
|
||||
case kRoundTiesToEven:
|
||||
@ -900,10 +913,10 @@ Decimal128 Decimal128::quantize(const Decimal128& reference,
|
||||
|
||||
auto normalizedThis = this->normalize();
|
||||
auto normalizedReferenceExponent =
|
||||
static_cast<std::int32_t>(reference.normalize().getBiasedExponent());
|
||||
static_cast<int32_t>(reference.normalize().getBiasedExponent());
|
||||
if (normalizedReferenceExponent != 0 &&
|
||||
(static_cast<std::int32_t>(normalizedThis.getBiasedExponent()) -
|
||||
normalizedReferenceExponent) > 33) {
|
||||
(static_cast<int32_t>(normalizedThis.getBiasedExponent()) - normalizedReferenceExponent) >
|
||||
33) {
|
||||
return normalizedThis;
|
||||
}
|
||||
return nonNormalizingQuantize(reference, signalingFlags, roundMode);
|
||||
@ -976,7 +989,7 @@ const std::uint64_t t17 = 100ull * 1000 * 1000 * 1000 * 1000 * 1000;
|
||||
// Computed by running the calculations in Python, and verified with static_assert.
|
||||
const std::uint64_t t34lo64 = 4003012203950112767ULL;
|
||||
#if defined(__GNUC__)
|
||||
MONGO_STATIC_ASSERT(t34lo64 == t17 * t17 - 1);
|
||||
static_assert(t34lo64 == t17 * t17 - 1, "precomputed constant is wrong");
|
||||
#endif
|
||||
// Mod t17 by 2^32 to get the low 32 bits of t17's binary representation
|
||||
const std::uint64_t t17lo32 = t17 % (1ull << 32);
|
||||
@ -1001,7 +1014,7 @@ const Decimal128 Decimal128::kSmallestNegative(1, 0, 0, 1);
|
||||
|
||||
// Get the representation of 0 (0E0).
|
||||
const Decimal128 Decimal128::kNormalizedZero(Decimal128::Value(
|
||||
{0, static_cast<std::uint64_t>(Decimal128::kExponentBias) << Decimal128::kExponentFieldPos}));
|
||||
{0, static_cast<uint64_t>(Decimal128::kExponentBias) << Decimal128::kExponentFieldPos}));
|
||||
|
||||
// Shift the format of the combination bits to the right position to get Inf and NaN
|
||||
// +Inf = 0111 1000 ... ... = 0x78 ... ..., -Inf = 1111 1000 ... ... = 0xf8 ... ...
|
||||
|
@ -33,13 +33,11 @@
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "mongo/config.h"
|
||||
|
||||
#include "mongo/util/assert_util.h"
|
||||
#include "mongo/util/if_constexpr.h"
|
||||
|
||||
namespace mongo {
|
||||
|
||||
@ -77,11 +75,10 @@ public:
|
||||
static const Decimal128 kPiOver180;
|
||||
static const Decimal128 k180OverPi;
|
||||
|
||||
static constexpr std::uint32_t kMaxBiasedExponent = 6143 + 6144;
|
||||
static const uint32_t kMaxBiasedExponent = 6143 + 6144;
|
||||
// Biased exponent of a Decimal128 with least significant digit in the units place
|
||||
static constexpr std::int32_t kExponentBias = 6143 + 33;
|
||||
static constexpr std::uint32_t kInfinityExponent =
|
||||
kMaxBiasedExponent + 1; // internal convention only
|
||||
static const int32_t kExponentBias = 6143 + 33;
|
||||
static const uint32_t kInfinityExponent = kMaxBiasedExponent + 1; // internal convention only
|
||||
|
||||
/**
|
||||
* This struct holds the raw data for IEEE 754-2008 data types
|
||||
@ -127,17 +124,17 @@ public:
|
||||
kInexact = 0x20,
|
||||
};
|
||||
|
||||
constexpr static bool hasFlag(std::uint32_t signalingFlags, SignalingFlag f) {
|
||||
static bool hasFlag(std::uint32_t signalingFlags, SignalingFlag f) {
|
||||
return ((signalingFlags & f) != 0u);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a valid Decimal can be constructed from the given arguments.
|
||||
*/
|
||||
constexpr static bool isValid(std::uint64_t sign,
|
||||
std::uint64_t exponent,
|
||||
std::uint64_t coefficientHigh,
|
||||
std::uint64_t coefficientLow) {
|
||||
static bool isValid(uint64_t sign,
|
||||
uint64_t exponent,
|
||||
uint64_t coefficientHigh,
|
||||
uint64_t coefficientLow) {
|
||||
if (coefficientHigh >= 0x1ed09bead87c0 &&
|
||||
(coefficientHigh != 0x1ed09bead87c0 || coefficientLow != 0x378d8e63ffffffff)) {
|
||||
return false;
|
||||
@ -152,10 +149,7 @@ public:
|
||||
/**
|
||||
* Construct a 0E0 valued Decimal128.
|
||||
*/
|
||||
constexpr Decimal128()
|
||||
: _value{0,
|
||||
static_cast<std::uint64_t>(Decimal128::kExponentBias)
|
||||
<< Decimal128::kExponentFieldPos} {}
|
||||
Decimal128() : _value(kNormalizedZero._value) {}
|
||||
|
||||
/**
|
||||
* This constructor takes in a raw decimal128 type, which consists of two
|
||||
@ -168,15 +162,16 @@ public:
|
||||
* Constructs a Decimal128 from parts, dealing with proper encoding of the combination field.
|
||||
* Assumes that the value will be inside the valid range of finite values. (No NaN/Inf, etc.)
|
||||
*/
|
||||
constexpr Decimal128(std::uint64_t sign,
|
||||
std::uint64_t exponent,
|
||||
std::uint64_t coefficientHigh,
|
||||
std::uint64_t coefficientLow)
|
||||
: _value(_valueFromParts(sign, exponent, coefficientHigh, coefficientLow)) {}
|
||||
Decimal128(uint64_t sign, uint64_t exponent, uint64_t coefficientHigh, uint64_t coefficientLow)
|
||||
: _value(
|
||||
Value{coefficientLow,
|
||||
(sign << kSignFieldPos) | (exponent << kExponentFieldPos) | coefficientHigh}) {
|
||||
dassert(isValid(sign, exponent, coefficientHigh, coefficientLow));
|
||||
}
|
||||
|
||||
template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
|
||||
constexpr explicit Decimal128(T v)
|
||||
: Decimal128(v < 0 ? 1 : 0, kExponentBias, 0, _makeCoefficientLow(v)) {}
|
||||
explicit Decimal128(std::int32_t int32Value);
|
||||
explicit Decimal128(std::int64_t int64Value);
|
||||
explicit Decimal128(std::uint64_t uint64Value);
|
||||
|
||||
/**
|
||||
* This constructor takes a double and constructs a Decimal128 object given a roundMode, either
|
||||
@ -212,15 +207,13 @@ public:
|
||||
/**
|
||||
* This function gets the inner Value struct storing a Decimal128 value.
|
||||
*/
|
||||
constexpr Value getValue() const {
|
||||
return _value;
|
||||
}
|
||||
Value getValue() const;
|
||||
|
||||
/**
|
||||
* Extracts the biased exponent from the combination field.
|
||||
*/
|
||||
constexpr std::uint32_t getBiasedExponent() const {
|
||||
const std::uint64_t combo = _getCombinationField();
|
||||
uint32_t getBiasedExponent() const {
|
||||
const uint64_t combo = _getCombinationField();
|
||||
if (combo < kCombinationNonCanonical)
|
||||
return combo >> 3;
|
||||
|
||||
@ -233,7 +226,7 @@ public:
|
||||
* Returns the high 49 bits of the 113-bit binary encoded coefficient. Returns 0 for
|
||||
* non-canonical or non-finite numbers.
|
||||
*/
|
||||
constexpr std::uint64_t getCoefficientHigh() const {
|
||||
uint64_t getCoefficientHigh() const {
|
||||
return _getCombinationField() < kCombinationNonCanonical
|
||||
? _value.high64 & kCanonicalCoefficientHighFieldMask
|
||||
: 0;
|
||||
@ -243,7 +236,7 @@ public:
|
||||
* Returns the low 64 bits of the 113-bit binary encoded coefficient. Returns 0 for
|
||||
* non-canonical or non-finite numbers.
|
||||
*/
|
||||
constexpr std::uint64_t getCoefficientLow() const {
|
||||
uint64_t getCoefficientLow() const {
|
||||
return _getCombinationField() < kCombinationNonCanonical ? _value.low64 : 0;
|
||||
}
|
||||
|
||||
@ -526,16 +519,15 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr static std::uint8_t kSignFieldPos = 64 - 1;
|
||||
constexpr static std::uint8_t kCombinationFieldPos = kSignFieldPos - 17;
|
||||
constexpr static std::uint64_t kCombinationFieldMask = (1 << 17) - 1;
|
||||
constexpr static std::uint64_t kExponentFieldPos = kCombinationFieldPos + 3;
|
||||
constexpr static std::uint64_t kCoefficientContinuationFieldMask =
|
||||
(1ull << kCombinationFieldPos) - 1;
|
||||
constexpr static std::uint64_t kCombinationNonCanonical = 3 << 15;
|
||||
constexpr static std::uint64_t kCombinationInfinity = 0x1e << 12;
|
||||
constexpr static std::uint64_t kCombinationNaN = 0x1f << 12;
|
||||
constexpr static std::uint64_t kCanonicalCoefficientHighFieldMask = (1ull << 49) - 1;
|
||||
static const uint8_t kSignFieldPos = 64 - 1;
|
||||
static const uint8_t kCombinationFieldPos = kSignFieldPos - 17;
|
||||
static const uint64_t kCombinationFieldMask = (1 << 17) - 1;
|
||||
static const uint64_t kExponentFieldPos = kCombinationFieldPos + 3;
|
||||
static const uint64_t kCoefficientContinuationFieldMask = (1ull << kCombinationFieldPos) - 1;
|
||||
static const uint64_t kCombinationNonCanonical = 3 << 15;
|
||||
static const uint64_t kCombinationInfinity = 0x1e << 12;
|
||||
static const uint64_t kCombinationNaN = 0x1f << 12;
|
||||
static const uint64_t kCanonicalCoefficientHighFieldMask = (1ull << 49) - 1;
|
||||
|
||||
std::string _convertToScientificNotation(StringData coefficient, int adjustedExponent) const;
|
||||
std::string _convertToStandardDecimalNotation(StringData coefficient, int exponent) const;
|
||||
@ -550,35 +542,10 @@ private:
|
||||
std::uint32_t* signalingFlags,
|
||||
RoundingMode roundMode = kRoundTiesToEven) const;
|
||||
|
||||
constexpr std::uint64_t _getCombinationField() const {
|
||||
uint64_t _getCombinationField() const {
|
||||
return (_value.high64 >> kCombinationFieldPos) & kCombinationFieldMask;
|
||||
}
|
||||
|
||||
constexpr static Value _valueFromParts(std::uint64_t sign,
|
||||
std::uint64_t exponent,
|
||||
std::uint64_t coefficientHigh,
|
||||
std::uint64_t coefficientLow) {
|
||||
// For constexpr's sake the invariant must be compiled only if !isValid().
|
||||
if (!isValid(sign, exponent, coefficientHigh, coefficientLow)) {
|
||||
invariant(false, "invalid arguments to Decimal128()");
|
||||
}
|
||||
|
||||
return Value{coefficientLow,
|
||||
(sign << kSignFieldPos) | (exponent << kExponentFieldPos) | coefficientHigh};
|
||||
}
|
||||
|
||||
// Constructs the absolute value of v as a uint64_t in a constexpr-permitted way.
|
||||
template <typename T>
|
||||
constexpr std::uint64_t _makeCoefficientLow(T i) {
|
||||
// if constexpr to avoid MSVC warnings.
|
||||
IF_CONSTEXPR(std::is_signed_v<T>) {
|
||||
return i < 0 ? static_cast<std::uint64_t>(-i) : static_cast<std::uint64_t>(i);
|
||||
}
|
||||
else {
|
||||
return static_cast<std::uint64_t>(i);
|
||||
}
|
||||
}
|
||||
|
||||
Value _value;
|
||||
};
|
||||
} // namespace mongo
|
||||
|
@ -31,7 +31,6 @@
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <fmt/format.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
@ -41,68 +40,80 @@
|
||||
|
||||
namespace mongo {
|
||||
|
||||
using namespace fmt::literals;
|
||||
|
||||
// Tests for Decimal128 constructors
|
||||
TEST(Decimal128Test, TestDefaultConstructor) {
|
||||
Decimal128 d;
|
||||
ASSERT_TRUE(d.isBinaryEqual(Decimal128(0)));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
using Lim = std::numeric_limits<T>;
|
||||
TEST(Decimal128Test, TestInt32ConstructorZero) {
|
||||
int32_t intZero = 0;
|
||||
Decimal128 d(intZero);
|
||||
Decimal128::Value val = d.getValue();
|
||||
// 0x3040000000000000 0000000000000000 = +0E+0
|
||||
uint64_t highBytes = 0x3040000000000000ull;
|
||||
uint64_t lowBytes = 0x0000000000000000ull;
|
||||
ASSERT_EQUALS(val.high64, highBytes);
|
||||
ASSERT_EQUALS(val.low64, lowBytes);
|
||||
}
|
||||
|
||||
TEST(Decimal128Test, TestConstructor) {
|
||||
// High bits of a positive Decimal128 with exponent 1.
|
||||
constexpr uint64_t posHigh = 0x3040000000000000;
|
||||
// High bits of a negative Decimal128 with exponent 1.
|
||||
constexpr uint64_t negHigh = 0xb040000000000000;
|
||||
TEST(Decimal128Test, TestInt32ConstructorMax) {
|
||||
int32_t intMax = std::numeric_limits<int32_t>::max();
|
||||
Decimal128 d(intMax);
|
||||
Decimal128::Value val = d.getValue();
|
||||
// 0x3040000000000000 000000007fffffff = +2147483647E+0
|
||||
uint64_t highBytes = 0x3040000000000000ull;
|
||||
uint64_t lowBytes = 0x000000007fffffffull;
|
||||
ASSERT_EQUALS(val.high64, highBytes);
|
||||
ASSERT_EQUALS(val.low64, lowBytes);
|
||||
}
|
||||
|
||||
#define TEST_CTOR(N, HIGH64, LOW64) \
|
||||
ASSERT_EQ(Decimal128{N}.getValue().high64, static_cast<uint64_t>(HIGH64)); \
|
||||
ASSERT_EQ(Decimal128{N}.getValue().low64, static_cast<uint64_t>(LOW64));
|
||||
TEST(Decimal128Test, TestInt32ConstructorMin) {
|
||||
int32_t intMin = std::numeric_limits<int32_t>::lowest();
|
||||
Decimal128 d(intMin);
|
||||
Decimal128::Value val = d.getValue();
|
||||
// 0xb040000000000000 000000007fffffff = -2147483648E+0
|
||||
uint64_t highBytes = 0xb040000000000000ull;
|
||||
uint64_t lowBytes = 0x0000000080000000ull;
|
||||
ASSERT_EQUALS(val.high64, highBytes);
|
||||
ASSERT_EQUALS(val.low64, lowBytes);
|
||||
}
|
||||
|
||||
TEST_CTOR(int8_t{0}, posHigh, 0); // +0E+0
|
||||
TEST_CTOR(Lim<int8_t>::lowest(), negHigh, uint64_t{1} << 7);
|
||||
TEST_CTOR(Lim<int8_t>::max(), posHigh, (uint64_t{1} << 7) - 1);
|
||||
TEST_CTOR(int8_t{5}, posHigh, 0x5);
|
||||
TEST(Decimal128Test, TestInt64ConstructorZero) {
|
||||
int64_t longZero = 0;
|
||||
Decimal128 d(longZero);
|
||||
Decimal128::Value val = d.getValue();
|
||||
// 0x3040000000000000 0000000000000000 = +0E+0
|
||||
uint64_t highBytes = 0x3040000000000000ull;
|
||||
uint64_t lowBytes = 0x0000000000000000ull;
|
||||
ASSERT_EQUALS(val.high64, highBytes);
|
||||
ASSERT_EQUALS(val.low64, lowBytes);
|
||||
}
|
||||
|
||||
TEST_CTOR(uint8_t{0}, posHigh, 0);
|
||||
TEST_CTOR(Lim<uint8_t>::max(), posHigh, (uint64_t{1} << 8) - 1);
|
||||
TEST_CTOR(uint8_t{5}, posHigh, 0x5);
|
||||
TEST(Decimal128Test, TestInt64ConstructorMax) {
|
||||
int64_t longMax = std::numeric_limits<long long>::max();
|
||||
Decimal128 d(longMax);
|
||||
Decimal128::Value val = d.getValue();
|
||||
// 0x3040000000000000 7fffffffffffffff = +9223372036854775807E+0
|
||||
uint64_t highBytes = 0x3040000000000000ull;
|
||||
uint64_t lowBytes = 0x7fffffffffffffffull;
|
||||
ASSERT_EQUALS(val.high64, highBytes);
|
||||
ASSERT_EQUALS(val.low64, lowBytes);
|
||||
}
|
||||
|
||||
TEST_CTOR(int16_t{0}, posHigh, 0);
|
||||
TEST_CTOR(Lim<int16_t>::lowest(), negHigh, uint64_t{1} << 15);
|
||||
TEST_CTOR(Lim<int16_t>::max(), posHigh, (uint64_t{1} << 15) - 1);
|
||||
TEST_CTOR(int16_t{5}, posHigh, 0x5);
|
||||
|
||||
TEST_CTOR(uint16_t{0}, posHigh, 0);
|
||||
TEST_CTOR(Lim<uint16_t>::max(), posHigh, (uint64_t{1} << 16) - 1);
|
||||
TEST_CTOR(uint16_t{5}, posHigh, 0x5);
|
||||
|
||||
TEST_CTOR(int32_t{0}, posHigh, 0);
|
||||
TEST_CTOR(Lim<int32_t>::lowest(), negHigh, uint64_t{1} << 31);
|
||||
TEST_CTOR(Lim<int32_t>::max(), posHigh, (uint64_t{1} << 31) - 1);
|
||||
TEST_CTOR(int32_t{5}, posHigh, 0x5);
|
||||
|
||||
TEST_CTOR(uint32_t{0}, posHigh, 0);
|
||||
TEST_CTOR(Lim<uint32_t>::max(), posHigh, (uint64_t{1} << 32) - 1);
|
||||
TEST_CTOR(uint32_t{5}, posHigh, 0x5);
|
||||
|
||||
TEST_CTOR(int64_t{0}, posHigh, 0);
|
||||
TEST_CTOR(Lim<int64_t>::lowest(), negHigh, uint64_t{1} << 63);
|
||||
TEST_CTOR(Lim<int64_t>::max(), posHigh, (uint64_t{1} << 63) - 1);
|
||||
TEST_CTOR(int64_t{5}, posHigh, 0x5);
|
||||
|
||||
TEST_CTOR(uint64_t{0}, posHigh, 0);
|
||||
TEST_CTOR(Lim<uint64_t>::max(), posHigh, Lim<uint64_t>::max());
|
||||
TEST_CTOR(uint64_t{5}, posHigh, 0x5);
|
||||
|
||||
#undef TEST_CTOR
|
||||
TEST(Decimal128Test, TestInt64ConstructorMin) {
|
||||
int64_t longMin = std::numeric_limits<long long>::lowest();
|
||||
Decimal128 d(longMin);
|
||||
Decimal128::Value val = d.getValue();
|
||||
// 0xb040000000000000 8000000000000000 = -9223372036854775808E+0
|
||||
uint64_t highBytes = 0xb040000000000000;
|
||||
uint64_t lowBytes = 0x8000000000000000;
|
||||
ASSERT_EQUALS(val.high64, highBytes);
|
||||
ASSERT_EQUALS(val.low64, lowBytes);
|
||||
}
|
||||
|
||||
TEST(Decimal128Test, TestPartsConstructor) {
|
||||
constexpr Decimal128 expected(10);
|
||||
Decimal128 expected(10);
|
||||
Decimal128 val(0LL, Decimal128::kExponentBias, 0LL, 10LL);
|
||||
ASSERT_EQUALS(val.getValue().low64, expected.getValue().low64);
|
||||
ASSERT_EQUALS(val.getValue().low64, expected.getValue().low64);
|
||||
@ -287,19 +298,17 @@ TEST(Decimal128Test, TestNonCanonicalDecimal) {
|
||||
// when encountered. However, the exponent and sign still matter.
|
||||
|
||||
// 0x6c10000000000000 0000000000000000 = non-canonical 0, all ignored bits clear
|
||||
constexpr Decimal128 nonCanonical0E0(Decimal128::Value{0, 0x6c10000000000000ull});
|
||||
Decimal128 nonCanonical0E0(Decimal128::Value{0, 0x6c10000000000000ull});
|
||||
std::string zeroE0 = nonCanonical0E0.toString();
|
||||
ASSERT_EQUALS(zeroE0, "0");
|
||||
|
||||
// 0xec100000deadbeef 0123456789abcdef = non-canonical -0, random stuff in ignored bits
|
||||
constexpr Decimal128 nonCanonicalM0E0(
|
||||
Decimal128::Value{0x0123456789abcdefull, 0xec100000deadbeefull});
|
||||
Decimal128 nonCanonicalM0E0(Decimal128::Value{0x0123456789abcdefull, 0xec100000deadbeefull});
|
||||
std::string minusZeroE0 = nonCanonicalM0E0.toString();
|
||||
ASSERT_EQUALS(minusZeroE0, "-0");
|
||||
|
||||
// 0x6c11fffffffffffff ffffffffffffffff = non-canonical 0.000, all ignored bits set
|
||||
constexpr Decimal128 nonCanonical0E3(
|
||||
Decimal128::Value{0xffffffffffffffffull, 0x6c11ffffffffffffull});
|
||||
Decimal128 nonCanonical0E3(Decimal128::Value{0xffffffffffffffffull, 0x6c11ffffffffffffull});
|
||||
std::string zeroE3 = nonCanonical0E3.toString();
|
||||
ASSERT_EQUALS(zeroE3, "0E+3");
|
||||
|
||||
@ -318,13 +327,13 @@ TEST(Decimal128Test, TestNonCanonicalDecimal) {
|
||||
|
||||
// Tests for absolute value function
|
||||
TEST(Decimal128Test, TestAbsValuePos) {
|
||||
constexpr Decimal128 d(25);
|
||||
Decimal128 d(25);
|
||||
Decimal128 dAbs = d.toAbs();
|
||||
ASSERT_TRUE(dAbs.isEqual(d));
|
||||
}
|
||||
|
||||
TEST(Decimal128Test, TestAbsValueNeg) {
|
||||
constexpr Decimal128 d(-25);
|
||||
Decimal128 d(-25);
|
||||
Decimal128 dAbs = d.toAbs();
|
||||
ASSERT_TRUE(dAbs.isEqual(Decimal128(25)));
|
||||
}
|
||||
@ -949,8 +958,8 @@ TEST(Decimal128Test, TestDecimal128DivideSignaling) {
|
||||
|
||||
// Test Decimal128 special comparisons
|
||||
TEST(Decimal128Test, TestDecimal128IsZero) {
|
||||
constexpr Decimal128 d1(0);
|
||||
constexpr Decimal128 d2(500);
|
||||
Decimal128 d1(0);
|
||||
Decimal128 d2(500);
|
||||
ASSERT_TRUE(d1.isZero());
|
||||
ASSERT_FALSE(d2.isZero());
|
||||
}
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "mongo/platform/basic.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <fmt/format.h>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
@ -44,8 +43,6 @@ namespace mongo {
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace fmt::literals;
|
||||
|
||||
// Char values
|
||||
const signed char kCharMax = std::numeric_limits<signed char>::max();
|
||||
const int kCharMaxAsInt = kCharMax;
|
||||
@ -357,15 +354,8 @@ void integerToDecimal128() {
|
||||
v.emplace_back(-5);
|
||||
}
|
||||
|
||||
for (const Integer n : v) {
|
||||
auto d = representAs<Decimal128>(n);
|
||||
ASSERT(d);
|
||||
if (!d->isEqual(Decimal128(std::to_string(n)))) {
|
||||
FAIL(
|
||||
"Failed expectation, representAs<Decimal128>({}) == Decimal128({}),"
|
||||
" but !Decimal128({}).isEqual(Decimal128(std::to_string({}))"_format(
|
||||
n, d->toString(), d->toString(), n));
|
||||
}
|
||||
for (const auto& n : v) {
|
||||
ASSERT(representAs<Decimal128>(n)->isEqual(Decimal128(std::to_string(n))));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user