19 #include <gtest/gtest.h>
20 #include <boost/cstdint.hpp>
21 #include <boost/lexical_cast.hpp>
38 LOG(ERROR) << t1 <<
" != " << t2;
48 s.c_str(), s.size(), t, &parse_result);
49 EXPECT_EQ(expected_result, parse_result) <<
"Failed test string: " << s;
58 EXPECT_EQ(decimal.ToString(t), expected);
68 TEST(IntToDecimal, Basic) {
70 bool overflow =
false;
73 EXPECT_FALSE(overflow);
77 EXPECT_FALSE(overflow);
79 "32130.00000000000000000000000000000");
82 EXPECT_TRUE(overflow);
88 TEST(DoubleToDecimal, Basic) {
99 bool overflow =
false;
101 EXPECT_FALSE(overflow);
102 EXPECT_EQ(d4.
value(), 1);
106 EXPECT_FALSE(overflow);
107 EXPECT_EQ(d4.
value(), 1);
111 EXPECT_FALSE(overflow);
112 EXPECT_EQ(d4.
value(), 0);
116 EXPECT_FALSE(overflow);
117 EXPECT_EQ(d4.
value(), -1);
121 EXPECT_FALSE(overflow);
122 EXPECT_EQ(d4.
value(), 1);
126 EXPECT_FALSE(overflow);
127 EXPECT_EQ(d4.
value(), 0);
131 EXPECT_FALSE(overflow);
132 EXPECT_EQ(d4.
value(), -1);
137 EXPECT_FALSE(overflow);
138 EXPECT_EQ(d8.
value(), -10010000);
143 EXPECT_FALSE(overflow);
144 EXPECT_EQ(d16.
value(), -1000000000);
150 EXPECT_FALSE(overflow);
154 EXPECT_TRUE(overflow);
158 EXPECT_TRUE(overflow);
162 EXPECT_FALSE(overflow);
166 EXPECT_TRUE(overflow);
170 EXPECT_TRUE(overflow);
174 EXPECT_FALSE(overflow);
179 EXPECT_TRUE(overflow);
183 EXPECT_TRUE(overflow);
258 TEST(StringToDecimal, LargeDecimals) {
340 VerifyParse(
"99999999999999999999999999999999999999",
343 VerifyParse(
"99999999999999999999999999999999999999e1",
346 VerifyParse(
"999999999999999999999999999999999999990e-1",
349 VerifyParse(
"999999999999999999999999999999999.99999",
352 VerifyParse(
".99999999999999999999999999999999999999",
355 VerifyParse(
"-99999999999999999999999999999999999999",
358 VerifyParse(
"-999999999999999999999999999999999.99999",
361 VerifyParse(
"-.99999999999999999999999999999999999999",
364 VerifyParse(
"-.99999999999999999999999999999999999999e1",
367 VerifyParse(
"-.999999999999999999999999999999999999990e-1",
370 VerifyParse(
"-.999999999999999999999999999999999999990000000000000000e-20",
372 Decimal16Value(-result / DecimalUtil::GetScaleMultiplier<int128_t>(20)),
374 VerifyParse(
"100000000000000000000000000000000000000",
377 VerifyParse(
"-100000000000000000000000000000000000000",
383 bool overflow =
false;
395 EXPECT_TRUE(overflow);
398 one.Add<
int128_t>(t1, d_max, t1, 0, &overflow);
399 EXPECT_TRUE(overflow);
402 d_max.Add<
int128_t>(t1, d_max, t1, 0, &overflow);
403 EXPECT_TRUE(overflow);
406 result = d_max.
Add<
int128_t>(t1, zero, t1, 0, &overflow);
407 EXPECT_FALSE(overflow);
408 EXPECT_TRUE(result.
value() == d_max.value());
413 EXPECT_FALSE(overflow);
416 EXPECT_TRUE(result.
value() == d_max.value() - 1);
418 EXPECT_FALSE(overflow);
421 EXPECT_TRUE(result.value() == -(d_max.value() - 1));
422 result = d_max.Subtract<
int128_t>(t1, d_max, t1, 0, &overflow);
423 EXPECT_FALSE(overflow);
426 EXPECT_TRUE(result.value() == 0);
427 result = d_max.Subtract<
int128_t>(t1, zero, t1, 0, &overflow);
428 EXPECT_FALSE(overflow);
429 EXPECT_TRUE(result.value() == d_max.value());
433 result = d_max.Add<
int128_t>(t1, -one, t1, 0, &overflow);
434 EXPECT_FALSE(overflow);
435 EXPECT_TRUE(result.value() == d_max.value() - 1);
438 result = one.Add<
int128_t>(t1, -d_max, t1, 0, &overflow);
439 EXPECT_FALSE(overflow);
440 EXPECT_TRUE(result.value() == -(d_max.value() - 1));
443 result = d_max.Add<
int128_t>(t1, -d_max, t1, 0, &overflow);
444 EXPECT_FALSE(overflow);
445 EXPECT_TRUE(result.value() == 0);
448 result = d_max.Add<
int128_t>(t1, -zero, t1, 0, &overflow);
449 EXPECT_FALSE(overflow);
450 EXPECT_TRUE(result.value() == d_max.value());
454 d_max.Subtract<
int128_t>(t1, -one, t1, 0, &overflow);
455 EXPECT_TRUE(overflow);
456 one.Subtract<
int128_t>(t1, -d_max, t1, 0, &overflow);
457 EXPECT_TRUE(overflow);
460 d_max.Subtract<
int128_t>(t1, -d_max, t1, 0, &overflow);
461 EXPECT_TRUE(overflow);
464 result = d_max.Subtract<
int128_t>(t1, -zero, t1, 0, &overflow);
465 EXPECT_FALSE(overflow);
466 EXPECT_TRUE(result.value() == d_max.value());
470 result = d_max.Multiply<
int128_t>(t1, one, t1, 0, &overflow);
471 EXPECT_FALSE(overflow);
472 EXPECT_TRUE(result.value() == d_max.value());
475 result = d_max.Multiply<
int128_t>(t1, -one, t1, 0, &overflow);
476 EXPECT_FALSE(overflow);
477 EXPECT_TRUE(result.value() == -d_max.value());
480 result = d_max.Multiply<
int128_t>(t1, two, t1, 0, &overflow);
481 EXPECT_TRUE(overflow);
484 result = d_max.Multiply<
int128_t>(t1, -two, t1, 0, &overflow);
485 EXPECT_TRUE(overflow);
488 result = d_max.Multiply<
int128_t>(t1, d_max, t1, 0, &overflow);
489 EXPECT_TRUE(overflow);
492 result = d_max.Multiply<
int128_t>(t1, -d_max, t1, 0, &overflow);
493 EXPECT_TRUE(overflow);
497 result = zero.Multiply<
int128_t>(t1, one, t1, 0, &overflow);
498 EXPECT_FALSE(overflow);
499 EXPECT_TRUE(result.value() == 0);
502 result = one.Multiply<
int128_t>(t1, zero, t1, 0, &overflow);
503 EXPECT_FALSE(overflow);
504 EXPECT_TRUE(result.value() == 0);
507 result = zero.Multiply<
int128_t>(t1, zero, t1, 0, &overflow);
508 EXPECT_FALSE(overflow);
509 EXPECT_TRUE(result.value() == 0);
515 result = d_max.Add<
int128_t>(t1, zero, t2, 1, &overflow);
516 EXPECT_TRUE(overflow);
521 result = d3.
Add<
int128_t>(t1, zero, t2, 1, &overflow);
522 EXPECT_FALSE(overflow);
526 result = d3.
Add<
int128_t>(t1, one, t2, 1, &overflow);
527 EXPECT_FALSE(overflow);
534 result = d3.
Mod<
int128_t>(t1, d3, t3, 20, &is_nan, &overflow);
535 EXPECT_TRUE(overflow);
536 EXPECT_FALSE(is_nan);
539 result = d3.Mod<
int128_t>(t1, two, t1, 0, &is_nan, &overflow);
540 EXPECT_FALSE(overflow);
541 EXPECT_FALSE(is_nan);
544 result = d3.Mod<
int128_t>(t1, zero, t2, 1, &is_nan, &overflow);
552 TEST(DecimalTest, MultiplyScaleOverflow) {
553 bool overflow =
false;
561 EXPECT_TRUE(result.
value() == 0);
562 EXPECT_FALSE(overflow);
570 EXPECT_TRUE(result.
value() == 3);
571 EXPECT_FALSE(overflow);
612 double expected,
bool overflow) {
613 double actual_d = actual.ToDouble(t);
614 EXPECT_FALSE(overflow);
615 EXPECT_TRUE(fabs(actual_d - expected) <
MAX_ERROR)
616 << actual_d <<
" != " << expected;
619 TEST(DecimalArithmetic, Basic) {
632 bool overflow =
false;
635 t1_plus_2, d1_double + d2_double, overflow);
637 t1_plus_2, d1_double + d3_double, overflow);
639 t1_plus_2, d1_double - d2_double, overflow);
641 t1_plus_2, d1_double - d3_double, overflow);
643 t1_times_2, d1_double * d2_double, overflow);
645 t1_times_2, d1_double * d3_double, overflow);
648 TEST(DecimalArithmetic, Divide) {
653 for (
int numerator_p = 1; numerator_p <= 9; ++numerator_p) {
654 for (
int numerator_s = 0; numerator_s <= numerator_p; ++numerator_s) {
655 for (
int denominator_p = 1; denominator_p <= 3; ++denominator_p) {
656 for (
int denominator_s = 0; denominator_s <= denominator_p; ++denominator_s) {
661 bool is_overflow =
false;
664 double approx_y = y.ToDouble(t2);
666 double expected_r = approx_x / approx_y;
668 EXPECT_FALSE(is_nan);
669 EXPECT_FALSE(is_overflow);
670 if (fabs(approx_r - expected_r) >
MAX_ERROR) {
671 LOG(ERROR) << approx_r <<
" " << expected_r;
672 LOG(ERROR) << x.
ToString(t1) <<
"/" << y.ToString(t2)
682 bool is_overflow =
false;
685 EXPECT_TRUE(is_nan) <<
"Expected NaN, got: " << r;
686 EXPECT_FALSE(is_overflow);
696 EXPECT_TRUE(is_overflow);
697 EXPECT_FALSE(is_nan);
700 TEST(DecimalArithmetic, DivideLargeScales) {
705 const char* data =
"319391280635.61476055";
707 StringParser::StringToDecimal<int128_t>(data, strlen(data), t1, &result);
710 bool is_overflow =
false;
713 EXPECT_FALSE(is_nan);
714 EXPECT_FALSE(is_overflow);
719 EXPECT_FALSE(is_nan);
720 EXPECT_FALSE(is_overflow);
726 int precision = rand() % max_precision;
727 for (
int i = 0; i < precision; ++i) {
728 int digit = rand() % 10;
729 val = val * 10 + digit;
735 if (x < y)
return -1;
741 TEST(DecimalArithmetic, RandTesting) {
742 int NUM_ITERS = 1000000;
744 LOG(ERROR) <<
"Seed: " << seed;
745 for (
int i = 0; i < NUM_ITERS; ++i) {
747 int p1 = rand() % 12 + 1;
748 int s1 = rand() % min(4, p1);
749 int p2 = rand() % 12 + 1;
750 int s2 = rand() % min(4, p2);
757 double t2_d = dec2.ToDouble(t2);
761 bool overflow =
false;
763 add_t, t1_d + t2_d, overflow);
765 add_t, t1_d - t2_d, overflow);
767 TODO: doubles are not precise enough
for this
773 t1, dec2, t2, multiply_t.
scale), multiply_t, t1_d * t2_d);
774 if (dec2.value() != 0) {
776 t1, dec2, t2, divide_t.
scale), divide_t, t1_d / t2_d);
781 EXPECT_TRUE(dec1.
Compare(t1, dec1, t1) == 0);
782 EXPECT_TRUE(dec2.Compare(t2, dec2, t2) == 0);
788 int main(
int argc,
char **argv) {
789 ::testing::InitGoogleTest(&argc, argv);
791 return RUN_ALL_TESTS();
static DecimalValue FromDouble(const ColumnType &t, double d, bool *overflow)
int main(int argc, char **argv)
int precision
Only set if type == TYPE_DECIMAL.
DecimalValue< int128_t > Decimal16Value
void VerifyEquals(const DecimalValue< T > &t1, const DecimalValue< T > &t2)
DecimalValue< RESULT_T > Subtract(const ColumnType &this_type, const DecimalValue &other, const ColumnType &other_type, int result_scale, bool *overflow) const
static int128_t MAX_UNSCALED_DECIMAL
Maximum absolute value of int128_t that we use. This is 38 digits of 9's.
DecimalValue< int64_t > Decimal8Value
DecimalValue< int32_t > Decimal4Value
ColumnType GetResultType(const ColumnType &t1, const ColumnType &t2, Op op)
int DoubleCompare(double x, double y)
static const double MAX_ERROR
DecimalValue< RESULT_T > Divide(const ColumnType &this_type, const DecimalValue &other, const ColumnType &other_type, int result_scale, bool *is_nan, bool *overflow) const
is_nan is set to true if 'other' is 0. The value returned is undefined.
static DecimalValue FromInt(const ColumnType &t, int64_t d, bool *overflow)
Assigns *result as a decimal.
std::string ToString(const ColumnType &type) const
static void InitMaxUnscaledDecimal()
Initializes MAX_UNSCALED_DECIMAL. Must be called once before using it.
DecimalValue< T > RandDecimal(int max_precision)
void VerifyToString(const T &decimal, const ColumnType &t, const string &expected)
void VerifyFuzzyEquals(const T &actual, const ColumnType &t, double expected, bool overflow)
DecimalValue< RESULT_T > Multiply(const ColumnType &this_type, const DecimalValue &other, const ColumnType &other_type, int result_scale, bool *overflow) const
DecimalValue< RESULT_T > Mod(const ColumnType &this_type, const DecimalValue &other, const ColumnType &other_type, int result_scale, bool *is_nan, bool *overflow) const
is_nan is set to true if 'other' is 0. The value returned is undefined.
void VerifyParse(const string &s, const ColumnType &t, const DecimalValue< T > &expected_val, StringParser::ParseResult expected_result)
int Compare(const DecimalValue &other) const
static ColumnType CreateDecimalType(int precision, int scale)
DecimalValue< RESULT_T > Add(const ColumnType &this_type, const DecimalValue &other, const ColumnType &other_type, int result_scale, bool *overflow) const
double ToDouble(const ColumnType &type) const
Returns an approximate double for this decimal.
__int128_t int128_t
We use the c++ int128_t type. This is stored using 16 bytes and very performant.
void StringToAllDecimals(const string &s, const ColumnType &t, int32_t val, StringParser::ParseResult result)