From bb70f845fbb04e0c6c72f58e2564a4a2a4d4009f Mon Sep 17 00:00:00 2001 From: Roman Nozdrin Date: Thu, 3 Dec 2020 12:37:19 +0000 Subject: [PATCH] Trim up Decimal comparison --- datatypes/mcs_decimal.cpp | 14 +- datatypes/mcs_decimal.h | 228 ++++----------- tests/mcs_decimal-tests.cpp | 551 ++++++++++++++++++++++++++++++++---- 3 files changed, 555 insertions(+), 238 deletions(-) diff --git a/datatypes/mcs_decimal.cpp b/datatypes/mcs_decimal.cpp index 37bbcf81e..6df2061fa 100644 --- a/datatypes/mcs_decimal.cpp +++ b/datatypes/mcs_decimal.cpp @@ -15,13 +15,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include #include #include "utils/common/branchpred.h" #include "mcs_decimal.h" -#include "exceptclasses.h" -#include "dataconvert.h" namespace datatypes { @@ -31,19 +28,16 @@ namespace datatypes int128_t quot; int128_t rem; lldiv_t_128() : quot(0), rem(0) {} + lldiv_t_128(const int128_t& a_quot, const int128_t& a_rem) + : quot(a_quot), rem(a_rem) {} }; inline lldiv_t_128 lldiv128(const int128_t& dividend, const int128_t& divisor) { - lldiv_t_128 res; - if (UNLIKELY(divisor == 0) || UNLIKELY(dividend == 0)) - return res; + return lldiv_t_128(); - res.quot = dividend / divisor; - res.rem = dividend % divisor; - - return res; + return lldiv_t_128(dividend / divisor, dividend % divisor); } template #include #include +#include #include "mcs_basic_types.h" #include "exceptclasses.h" #include "widedecimalutils.h" @@ -441,226 +442,97 @@ class Decimal: public TSInt128 return (std::get<0>(integralFractionalDivisor) % div.getValue()) * std::get<2>(integralFractionalDivisor) + std::get<1>(integralFractionalDivisor); } - bool operator==(const Decimal& rhs) const + template + bool cmpOperatorTemplate(const Decimal& rhs) const { + Op128 op128; + Op64 op64; if (precision > datatypes::INT64MAXPRECISION && rhs.precision > datatypes::INT64MAXPRECISION) { if (scale == rhs.scale) - return s128Value == rhs.s128Value; + return op128(s128Value, rhs.s128Value); else - return (datatypes::Decimal::compare(*this, rhs) == 0); + return op64(datatypes::Decimal::compare(*this, rhs), 0); } else if (precision > datatypes::INT64MAXPRECISION && rhs.precision <= datatypes::INT64MAXPRECISION) { - const_cast(rhs).s128Value = rhs.value; if (scale == rhs.scale) - return s128Value == rhs.s128Value; + { + return op128(s128Value, rhs.s128Value); + } else - return (datatypes::Decimal::compare(*this, rhs) == 0); + { + // comp_op(compare(l,r),0) + return op64(datatypes::Decimal::compare( + *this, + Decimal(TSInt128(rhs.value), + rhs.scale, + rhs.precision)), + 0); + } } else if (precision <= datatypes::INT64MAXPRECISION && rhs.precision > datatypes::INT64MAXPRECISION) { if (scale == rhs.scale) - return (int128_t) value == rhs.s128Value; + { + return op128((int128_t) value, rhs.s128Value); + } else - return (datatypes::Decimal::compare(Decimal(0, scale, precision, (int128_t) value), rhs) == 0); + { + // comp_op(compare(l,r),0) + return op64(datatypes::Decimal::compare( + Decimal( + TSInt128(value), + scale, + precision), + rhs), + 0); + } } else { if (scale == rhs.scale) - return value == rhs.value; + return op64(value, rhs.value); else - return (decimalComp(rhs) == 0); + return op64(decimalComp(rhs), 0); } } + bool operator==(const Decimal& rhs) const + { + return cmpOperatorTemplate, + std::equal_to>(rhs); + } + bool operator>(const Decimal& rhs) const { - if (precision > datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return s128Value > rhs.s128Value; - else - return (datatypes::Decimal::compare(*this, rhs) > 0); - } - else if (precision > datatypes::INT64MAXPRECISION && - rhs.precision <= datatypes::INT64MAXPRECISION) - { - Decimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value); - - if (scale == rhstmp.scale) - return s128Value > rhstmp.s128Value; - else - return (datatypes::Decimal::compare(*this, rhstmp) > 0); - } - else if (precision <= datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return (int128_t) value > rhs.s128Value; - else - return (datatypes::Decimal::compare(Decimal(0, scale, precision, (int128_t) value), rhs) > 0); - } - else - { - if (scale == rhs.scale) - return value > rhs.value; - else - return (decimalComp(rhs) > 0); - } - } - - bool operator<(const Decimal& rhs) const - { - if (precision > datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return s128Value < rhs.s128Value; - else - return (datatypes::Decimal::compare(*this, rhs) < 0); - } - else if (precision > datatypes::INT64MAXPRECISION && - rhs.precision <= datatypes::INT64MAXPRECISION) - { - Decimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value); - - if (scale == rhstmp.scale) - return s128Value < rhstmp.s128Value; - else - return (datatypes::Decimal::compare(*this, rhstmp) < 0); - } - else if (precision <= datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return (int128_t) value < rhs.s128Value; - else - return (datatypes::Decimal::compare(Decimal(0, scale, precision, (int128_t) value), rhs) < 0); - } - else - { - if (scale == rhs.scale) - return value < rhs.value; - else - return (decimalComp(rhs) < 0); - } + return cmpOperatorTemplate, + std::greater>(rhs); } bool operator>=(const Decimal& rhs) const { - if (precision > datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return s128Value >= rhs.s128Value; - else - return (datatypes::Decimal::compare(*this, rhs) >= 0); - } - else if (precision > datatypes::INT64MAXPRECISION && - rhs.precision <= datatypes::INT64MAXPRECISION) - { - Decimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value); + return cmpOperatorTemplate, + std::greater_equal>(rhs); + } - if (scale == rhstmp.scale) - return s128Value >= rhstmp.s128Value; - else - return (datatypes::Decimal::compare(*this, rhstmp) >= 0); - } - else if (precision <= datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return (int128_t) value >= rhs.s128Value; - else - return (datatypes::Decimal::compare(Decimal(0, scale, precision, (int128_t) value), rhs) >= 0); - } - else - { - if (scale == rhs.scale) - return value >= rhs.value; - else - return (decimalComp(rhs) >= 0); - } + bool operator<(const Decimal& rhs) const + { + return !this->operator>=(rhs); } bool operator<=(const Decimal& rhs) const { - if (precision > datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return s128Value <= rhs.s128Value; - else - return (datatypes::Decimal::compare(*this, rhs) <= 0); - } - else if (precision > datatypes::INT64MAXPRECISION && - rhs.precision <= datatypes::INT64MAXPRECISION) - { - Decimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value); - - if (scale == rhstmp.scale) - return s128Value <= rhstmp.s128Value; - else - return (datatypes::Decimal::compare(*this, rhstmp) <= 0); - } - else if (precision <= datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return (int128_t) value <= rhs.s128Value; - else - return (datatypes::Decimal::compare(Decimal(0, scale, precision, (int128_t) value), rhs) <= 0); - } - else - { - if (scale == rhs.scale) - return value <= rhs.value; - else - return (decimalComp(rhs) <= 0); - } + return !this->operator>(rhs); } bool operator!=(const Decimal& rhs) const { - if (precision > datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return s128Value != rhs.s128Value; - else - return (datatypes::Decimal::compare(*this, rhs) != 0); - } - else if (precision > datatypes::INT64MAXPRECISION && - rhs.precision <= datatypes::INT64MAXPRECISION) - { - Decimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value); - - if (scale == rhstmp.scale) - return s128Value != rhstmp.s128Value; - else - return (datatypes::Decimal::compare(*this, rhstmp) != 0); - } - else if (precision <= datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return (int128_t) value != rhs.s128Value; - else - return (datatypes::Decimal::compare(Decimal(0, scale, precision, (int128_t) value), rhs) != 0); - } - else - { - if (scale == rhs.scale) - return value != rhs.value; - else - return (decimalComp(rhs) != 0); - } + return !this->operator==(rhs); } inline bool isTSInt128ByPrecision() const diff --git a/tests/mcs_decimal-tests.cpp b/tests/mcs_decimal-tests.cpp index d0e14aa1b..62598d7af 100644 --- a/tests/mcs_decimal-tests.cpp +++ b/tests/mcs_decimal-tests.cpp @@ -23,63 +23,514 @@ #include "mcs_decimal.h" #include "dataconvert.h" -TEST(Decimal, compareCheck) +TEST(Decimal, compareCheckInt64) { - // L values = R value, L scale < R scale - execplan::IDB_Decimal l, r; - l.scale = 20; - l.precision = 38; - l.s128Value = 42; + // remainder-based checks + // Equality checks + // l value = r value, L scale = R scale + { + datatypes::Decimal l(420, 10, 18); + datatypes::Decimal r(420, 10, 18); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } - r.scale = 21; - l.precision = 38; - r.s128Value = 420; - EXPECT_EQ(0, datatypes::Decimal::compare(l, r)); - // L values = R value, L scale > R scale - l.scale = 21; - l.precision = 38; - l.s128Value = 420; + // l value > r value, L scale < R scale + { + datatypes::Decimal l(420, 11, 18); + datatypes::Decimal r(42, 10, 18); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } - r.scale = 20; - l.precision = 38; - r.s128Value = 42; - EXPECT_EQ(0, datatypes::Decimal::compare(l, r)); - // L values > R value, L scale < R scale - l.scale = 20; - l.precision = 38; - l.s128Value = 999999; + // l value < r value, L scale > R scale + { + datatypes::Decimal l(42, 10, 18); + datatypes::Decimal r(420, 11, 18); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } - r.scale = 21; - l.precision = 38; - r.s128Value = 420; - EXPECT_EQ(1, datatypes::Decimal::compare(l, r)); - // L values > R value, L scale > R scale - l.scale = 21; - l.precision = 38; - l.s128Value = 99999999; + // Inequality checks + // l value = r value, L scale < R scale + { + datatypes::Decimal l(42, 10, 18); + datatypes::Decimal r(42, 13, 18); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } - r.scale = 20; - l.precision = 38; - r.s128Value = 420; - EXPECT_EQ(1, datatypes::Decimal::compare(l, r)); - // L values < R value, L scale < R scale - l.scale = 20; - l.precision = 38; - l.s128Value = 99; + // l value = r value, L scale < R scale + { + datatypes::Decimal l(42, 13, 18); + datatypes::Decimal r(42, 10, 18); + EXPECT_FALSE(l > r); + EXPECT_FALSE(l >= r); + EXPECT_FALSE(l == r); + } - r.scale = 21; - l.precision = 38; - r.s128Value = 42000; - EXPECT_EQ(-1, datatypes::Decimal::compare(l, r)); - // L values < R value, L scale > R scale - l.scale = 21; - l.precision = 38; - l.s128Value = 99; + // l value > r value, L scale > R scale + { + datatypes::Decimal l(420, 13, 18); + datatypes::Decimal r(42, 10, 18); + EXPECT_FALSE(l > r); + EXPECT_FALSE(l >= r); + EXPECT_FALSE(l == r); + } - r.scale = 20; - l.precision = 38; - r.s128Value = 420; - EXPECT_EQ(-1, datatypes::Decimal::compare(l, r)); + // l value > r value, L scale < R scale + { + datatypes::Decimal l(4200, 11, 18); + datatypes::Decimal r(42, 12, 18); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value < r value, L scale < R scale + { + datatypes::Decimal l(99, 10, 18); + datatypes::Decimal r(420, 11, 18); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value < r value, L scale < R scale + { + datatypes::Decimal l(42, 10, 18); + datatypes::Decimal r(420, 13, 18); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // quotinent-based checks + // l value = r value, L scale = R scale + { + datatypes::Decimal l(420, 1, 18); + datatypes::Decimal r(420, 1, 18); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } + + // l value > r value, L scale < R scale + { + datatypes::Decimal l(4200, 2, 18); + datatypes::Decimal r(420, 1, 18); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } + + // l value < r value, L scale > R scale + { + datatypes::Decimal l(42, 0, 18); + datatypes::Decimal r(420, 1, 18); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } + + // Inequality checks + // l value = r value, L scale < R scale + { + datatypes::Decimal l(42000, 0, 18); + datatypes::Decimal r(42000, 3, 18); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value = r value, L scale < R scale + { + datatypes::Decimal l(420000, 3, 18); + datatypes::Decimal r(420000, 0, 18); + EXPECT_FALSE(l > r); + EXPECT_FALSE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value > r value, L scale > R scale + { + datatypes::Decimal l(420000, 3, 18); + datatypes::Decimal r(42000, 0, 18); + EXPECT_FALSE(l > r); + EXPECT_FALSE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value > r value, L scale < R scale + { + datatypes::Decimal l(420000, 1, 18); + datatypes::Decimal r(4200, 2, 18); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value < r value, L scale < R scale + { + datatypes::Decimal l(990, 0, 18); + datatypes::Decimal r(4200, 1, 18); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value < r value, L scale < R scale + { + datatypes::Decimal l(420, 0, 18); + datatypes::Decimal r(4200, 3, 18); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } +} + +TEST(Decimal, compareCheckInt128) +{ + // remainer-based checks + // Equality checks + // l value = r value, L scale = R scale + { + datatypes::Decimal l(datatypes::TSInt128(420), 20, 38); + datatypes::Decimal r(datatypes::TSInt128(420), 20, 38); + EXPECT_EQ(0, datatypes::Decimal::compare(l, r)); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } + + // l value > r value, L scale < R scale + { + datatypes::Decimal l(datatypes::TSInt128(420), 21, 38); + datatypes::Decimal r(datatypes::TSInt128(42), 20, 38); + EXPECT_EQ(0, datatypes::Decimal::compare(l, r)); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } + + // l value < r value, L scale > R scale + { + datatypes::Decimal l(datatypes::TSInt128(42), 20, 38); + datatypes::Decimal r(datatypes::TSInt128(420), 21, 38); + EXPECT_EQ(0, datatypes::Decimal::compare(l, r)); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } + + // Inequality checks + // l value = r value, L scale < R scale + { + datatypes::Decimal l(datatypes::TSInt128(42), 20, 38); + datatypes::Decimal r(datatypes::TSInt128(42), 23, 38); + EXPECT_EQ(1, datatypes::Decimal::compare(l, r)); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value = r value, L scale < R scale + { + datatypes::Decimal l(datatypes::TSInt128(42), 23, 38); + datatypes::Decimal r(datatypes::TSInt128(42), 20, 38); + EXPECT_EQ(-1, datatypes::Decimal::compare(l, r)); + EXPECT_FALSE(l > r); + EXPECT_FALSE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value > r value, L scale > R scale + { + datatypes::Decimal l(datatypes::TSInt128(420), 23, 38); + datatypes::Decimal r(datatypes::TSInt128(42), 20, 38); + EXPECT_EQ(-1, datatypes::Decimal::compare(l, r)); + EXPECT_FALSE(l > r); + EXPECT_FALSE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value > r value, L scale < R scale + { + datatypes::Decimal l(datatypes::TSInt128(4200), 21, 38); + datatypes::Decimal r(datatypes::TSInt128(42), 22, 38); + EXPECT_EQ(1, datatypes::Decimal::compare(l, r)); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value < r value, L scale < R scale + { + datatypes::Decimal l(datatypes::TSInt128(99), 20, 38); + datatypes::Decimal r(datatypes::TSInt128(420), 21, 38); + EXPECT_EQ(1, datatypes::Decimal::compare(l, r)); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value < r value, L scale < R scale + { + datatypes::Decimal l(datatypes::TSInt128(42), 20, 38); + datatypes::Decimal r(datatypes::TSInt128(420), 23, 38); + EXPECT_EQ(1, datatypes::Decimal::compare(l, r)); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // quotinent-based checks + // l value = r value, L scale = R scale + { + datatypes::Decimal l(datatypes::TSInt128(420), 1, 38); + datatypes::Decimal r(datatypes::TSInt128(420), 1, 38); + EXPECT_EQ(0, datatypes::Decimal::compare(l, r)); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } + + // l value > r value, L scale < R scale + { + datatypes::Decimal l(datatypes::TSInt128(4200), 2, 38); + datatypes::Decimal r(datatypes::TSInt128(420), 1, 38); + EXPECT_EQ(0, datatypes::Decimal::compare(l, r)); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } + + // l value < r value, L scale > R scale + { + datatypes::Decimal l(datatypes::TSInt128(42), 0, 38); + datatypes::Decimal r(datatypes::TSInt128(420), 1, 38); + EXPECT_EQ(0, datatypes::Decimal::compare(l, r)); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } + + // Inequality checks + // l value = r value, L scale < R scale + { + datatypes::Decimal l(datatypes::TSInt128(42000), 0, 38); + datatypes::Decimal r(datatypes::TSInt128(42000), 3, 38); + EXPECT_EQ(1, datatypes::Decimal::compare(l, r)); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value = r value, L scale < R scale + { + datatypes::Decimal l(datatypes::TSInt128(420000), 3, 38); + datatypes::Decimal r(datatypes::TSInt128(420000), 0, 38); + EXPECT_EQ(-1, datatypes::Decimal::compare(l, r)); + EXPECT_FALSE(l > r); + EXPECT_FALSE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value > r value, L scale > R scale + { + datatypes::Decimal l(datatypes::TSInt128(420000), 3, 38); + datatypes::Decimal r(datatypes::TSInt128(42000), 0, 38); + EXPECT_EQ(-1, datatypes::Decimal::compare(l, r)); + EXPECT_FALSE(l > r); + EXPECT_FALSE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value > r value, L scale < R scale + { + datatypes::Decimal l(datatypes::TSInt128(420000), 1, 38); + datatypes::Decimal r(datatypes::TSInt128(4200), 2, 38); + EXPECT_EQ(1, datatypes::Decimal::compare(l, r)); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value < r value, L scale < R scale + { + datatypes::Decimal l(datatypes::TSInt128(990), 0, 38); + datatypes::Decimal r(datatypes::TSInt128(4200), 1, 38); + EXPECT_EQ(1, datatypes::Decimal::compare(l, r)); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value < r value, L scale < R scale + { + datatypes::Decimal l(datatypes::TSInt128(420), 0, 38); + datatypes::Decimal r(datatypes::TSInt128(4200), 3, 38); + EXPECT_EQ(1, datatypes::Decimal::compare(l, r)); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } +} + +TEST(Decimal, compareCheckInt64_Int128) +{ + // remainer-based checks + // Equality checks + // l value = r value, L scale = R scale + { + datatypes::Decimal l(420, 10, 18); + datatypes::Decimal r(datatypes::TSInt128(420), 10, 38); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } + + // l value > r value, L scale < R scale + { + datatypes::Decimal l(420, 11, 18); + datatypes::Decimal r(datatypes::TSInt128(42), 10, 38); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } + + // l value < r value, L scale > R scale + { + datatypes::Decimal l(42, 10, 18); + datatypes::Decimal r(datatypes::TSInt128(420), 11, 38); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } + + // Inequality checks + // l value = r value, L scale < R scale + { + datatypes::Decimal l(42, 10, 18); + datatypes::Decimal r(datatypes::TSInt128(42), 13, 38); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value = r value, L scale < R scale + { + datatypes::Decimal l(42, 13, 18); + datatypes::Decimal r(datatypes::TSInt128(42), 10, 38); + EXPECT_FALSE(l > r); + EXPECT_FALSE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value > r value, L scale > R scale + { + datatypes::Decimal l(420, 13, 18); + datatypes::Decimal r(datatypes::TSInt128(42), 10, 38); + EXPECT_FALSE(l > r); + EXPECT_FALSE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value > r value, L scale < R scale + { + datatypes::Decimal l(4200, 11, 18); + datatypes::Decimal r(datatypes::TSInt128(42), 12, 38); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value < r value, L scale < R scale + { + datatypes::Decimal l(99, 10, 18); + datatypes::Decimal r(datatypes::TSInt128(420), 11, 38); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value < r value, L scale < R scale + { + datatypes::Decimal l(42, 10, 18); + datatypes::Decimal r(datatypes::TSInt128(420), 13, 38); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // quotinent-based checks + // l value = r value, L scale = R scale + { + datatypes::Decimal l(420, 1, 18); + datatypes::Decimal r(datatypes::TSInt128(420), 1, 38); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } + + // l value > r value, L scale < R scale + { + datatypes::Decimal l(4200, 2, 18); + datatypes::Decimal r(datatypes::TSInt128(420), 1, 38); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } + + // l value < r value, L scale > R scale + { + datatypes::Decimal l(42, 0, 18); + datatypes::Decimal r(datatypes::TSInt128(420), 1, 38); + EXPECT_TRUE(l == r); + EXPECT_TRUE(l >= r); + } + + // Inequality checks + // l value = r value, L scale < R scale + { + datatypes::Decimal l(42000, 0, 18); + datatypes::Decimal r(datatypes::TSInt128(42000), 3, 38); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value = r value, L scale < R scale + { + datatypes::Decimal l(420000, 3, 18); + datatypes::Decimal r(datatypes::TSInt128(420000), 0, 38); + EXPECT_FALSE(l > r); + EXPECT_FALSE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value > r value, L scale > R scale + { + datatypes::Decimal l(420000, 3, 18); + datatypes::Decimal r(datatypes::TSInt128(42000), 0, 38); + EXPECT_FALSE(l > r); + EXPECT_FALSE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value > r value, L scale < R scale + { + datatypes::Decimal l(420000, 1, 18); + datatypes::Decimal r(datatypes::TSInt128(4200), 2, 38); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value < r value, L scale < R scale + { + datatypes::Decimal l(990, 0, 18); + datatypes::Decimal r(datatypes::TSInt128(4200), 1, 38); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } + + // l value < r value, L scale < R scale + { + datatypes::Decimal l(420, 0, 18); + datatypes::Decimal r(datatypes::TSInt128(4200), 3, 38); + EXPECT_TRUE(l > r); + EXPECT_TRUE(l >= r); + EXPECT_FALSE(l == r); + } } TEST(Decimal, additionNoOverflowCheck)