diff --git a/source/libs/decimal/src/decimal.c b/source/libs/decimal/src/decimal.c index 44c25b1605..b37090f228 100644 --- a/source/libs/decimal/src/decimal.c +++ b/source/libs/decimal/src/decimal.c @@ -204,47 +204,38 @@ static int32_t decimalVarFromStr(const char* str, int32_t len, DecimalVar* resul if (afterPoint) { if (!rounded && curPrec - 1 == maxPrecision(result->type) && str[pos] >= '5') { Decimal64 delta = {1}; - if (places > 1) { - int32_t scaleUp = places - 1; - while (scaleUp != 0) { - int32_t curScale = TMIN(17, scaleUp); - pOps->multiply(result->pDec, &SCALE_MULTIPLIER_64[curScale], WORD_NUM(Decimal64)); - scaleUp -= curScale; - } - result->precision += places - 1; - result->scale += places - 1; + int32_t scaleUp = places - 1; + while (scaleUp != 0) { + int32_t curScale = TMIN(17, scaleUp); + pOps->multiply(result->pDec, &SCALE_MULTIPLIER_64[curScale], WORD_NUM(Decimal64)); + scaleUp -= curScale; } + result->precision += places - 1; + result->scale += places - 1; pOps->add(result->pDec, &delta, WORD_NUM(Decimal64)); rounded = true; + places = 0; } - break; } else { return TSDB_CODE_DECIMAL_OVERFLOW; } } else { - if (afterPoint && result->precision == 0) { - result->precision = places; - result->scale = places; - } else { - result->precision += places; - if (afterPoint) { - result->scale += places; - } - while (places != 0) { - int32_t curScale = TMIN(17, places); - pOps->multiply(result->pDec, &SCALE_MULTIPLIER_64[curScale], WORD_NUM(Decimal64)); - places -= curScale; - } + result->precision += places; + if (afterPoint) { + result->scale += places; + } + while (places != 0) { + int32_t curScale = TMIN(17, places); + pOps->multiply(result->pDec, &SCALE_MULTIPLIER_64[curScale], WORD_NUM(Decimal64)); + places -= curScale; } Decimal64 digit = {str[pos] - '0'}; pOps->add(result->pDec, &digit, WORD_NUM(Decimal64)); places = 0; - break; } - } + } break; case 'e': case 'E': { - //result->exponent += atoi(str + pos + 1); stop = true; } break; default: @@ -252,8 +243,6 @@ static int32_t decimalVarFromStr(const char* str, int32_t len, DecimalVar* resul break; } } - if (rounded) { - } if (result->sign < 0) { pOps->negate(result->pDec); } diff --git a/source/libs/decimal/test/decimalTest.cpp b/source/libs/decimal/test/decimalTest.cpp index 4cd6722291..fb41136215 100644 --- a/source/libs/decimal/test/decimalTest.cpp +++ b/source/libs/decimal/test/decimalTest.cpp @@ -174,7 +174,7 @@ class Numeric { if (prec > NumericType::maxPrec) throw std::string("prec too big") + std::to_string(prec); int32_t code = dec_.fromStr(str, prec, scale) != 0; if (code != 0) { - cout << "failed to init decimal from str: " << str << "\t"; + cout << "failed to init decimal(" << (int32_t)prec << "," << (int32_t)scale << ") from str: " << str << "\t"; throw std::overflow_error(tstrerror(code)); } } @@ -904,6 +904,12 @@ void testDecimalFromStr(std::vector>& units) { TEST(decimal, decimalFromStr_all) { std::vector> units = { + {18, 18, "-0.0000000000000100000010000000900000009e10", "-0.000100000010000001", false}, + {18, 18, "-0.1999999999999999999e-1", "-0.020000000000000000", false}, + {18, 18, "-0.9999999999999999999e-1", "-0.100000000000000000", false}, + {18, 18, "-9.999999999999999999e-1", "", true}, + {10, 10, "-9.9999999e-2", "-0.0999999990", false}, + {10, 6, "9.99999e4", "", true}, {18, 4, "9.999999e1", "100.0000", false}, {18, 10, "1.23456e7", "12345600.0000000000", false}, {18, 18, "0.0000000000000000000000000010000000000000000199999e26", "0.100000000000000002", false},