HAWQ-1767. refactor decimalToFloat and floatToDecimal function
diff --git a/depends/dbcommon/src/dbcommon/function/typecast-func.cc b/depends/dbcommon/src/dbcommon/function/typecast-func.cc
index e49a206..958f13d 100644
--- a/depends/dbcommon/src/dbcommon/function/typecast-func.cc
+++ b/depends/dbcommon/src/dbcommon/function/typecast-func.cc
@@ -18,6 +18,7 @@
  */
 
 #include <cmath>
+#include <fstream>
 
 //#include <boost/lexical_cast.hpp>
 #include <boost/multiprecision/cpp_int.hpp>
@@ -317,6 +318,24 @@
 }
 
 template <typename TP>
+inline DecimalVar floatToDecimal(TP in) {
+  int64_t scale = 0;
+  while (true) {
+    if (scale >= 13) {
+      break;
+    }
+    if (abs(in - static_cast<int64_t>(in)) > 1e-8) {
+      in *= 10.0;
+      ++scale;
+    } else {
+      break;
+    }
+  }
+  Int128 int128 = static_cast<int64_t>(in);
+  return DecimalVar(int128.getHighBits(), int128.getLowBits(), scale);
+}
+
+template <typename TP>
 Datum TypeCast::castFloatTypeToDecimal(Datum *params, uint64_t size) {
   assert(size == 2 && "invalid input");
   Object *para = DatumGetValue<Object *>(params[1]);
@@ -332,7 +351,7 @@
       DecimalVar *ret = retScalar->allocateValue<DecimalVar>();
 
       TP val = DatumGetValue<TP>(srcScalar->value);
-      *ret = DecimalType::fromString(boost::lexical_cast<std::string>(val));
+      *ret = floatToDecimal(val);
     }
     return CreateDatum(retScalar);
   } else {
@@ -351,12 +370,57 @@
   return false;
 }
 
+template <int64_t n>
+constexpr uint64_t res2() {
+  return 2 * res2<n - 1>();
+}
+
+template <>
+constexpr uint64_t res2<1>() {
+  return 2;
+}
+
+template <typename TR>
+inline TR decimalToFloat(int64_t highbits, uint64_t lowbits, int64_t scale) {
+  TR exp[] = {
+      1.0,
+      10.0,
+      100.0,
+      1000.0,
+      10000.0,
+      100000.0,
+      1000000.0,
+      10000000.0,
+      100000000.0,
+      1000000000.0,
+      10000000000.0,
+      100000000000.0,
+      1000000000000.0,
+      10000000000000.0,
+      100000000000000.0,
+      1000000000000000.0,
+      10000000000000000.0,
+      100000000000000000.0,
+      1000000000000000000.0,
+      10000000000000000000.0,
+      100000000000000000000.0,
+  };
+  Int128 int128(highbits, lowbits);
+  int128.abs();
+  TR fval =
+      static_cast<TR>(int128.getHighBits()) * static_cast<TR>(res2<64>()) +
+      static_cast<TR>(int128.getLowBits());
+  if (scale <= 20)
+    fval /= exp[scale];
+  else
+    for (int32_t i = 0; i < scale; ++i) fval /= 10.0;
+  return highbits < 0 ? -fval : fval;
+}
+
 template <typename TR>
 Datum TypeCast::valCastDecimalToFloatType(DecimalVar *param) {
-  std::string strVal = dbcommon::DecimalType::toString(
-      param->highbits, param->lowbits, param->scale);
-  double fval = stod(strVal);
-  return CreateDatum(static_cast<TR>(fval));
+  return CreateDatum(static_cast<TR>(
+      decimalToFloat<TR>(param->highbits, param->lowbits, param->scale)));
 }
 
 template <typename TR>
@@ -393,19 +457,15 @@
         if (rnull[index]) {
           rdata[index] = 0;
         } else {
-          std::string strVecVal =
-              DecimalType::toString(hval[index], lval[index], sval[index]);
-          double fval = stod(strVecVal);
-          rdata[index] = static_cast<TR>(fval);
+          rdata[index] =
+              decimalToFloat<TR>(hval[index], lval[index], sval[index]);
         }
       }
     } else {
       for (uint64_t i = 0; i < sz; ++i) {
         auto index = (*sel)[i];
-        std::string strVecVal =
-            DecimalType::toString(hval[index], lval[index], sval[index]);
-        double fval = stod(strVecVal);
-        rdata[index] = static_cast<TR>(fval);
+        rdata[index] =
+            decimalToFloat<TR>(hval[index], lval[index], sval[index]);
       }
     }
   } else {
@@ -416,18 +476,12 @@
         if (rnull[i]) {
           rdata[i] = 0;
         } else {
-          std::string strVecVal =
-              DecimalType::toString(hval[i], lval[i], sval[i]);
-          double fval = stod(strVecVal);
-          rdata[i] = static_cast<TR>(fval);
+          rdata[i] = decimalToFloat<TR>(hval[i], lval[i], sval[i]);
         }
       }
     } else {
       for (uint64_t i = 0; i < sz; ++i) {
-        std::string strVecVal =
-            DecimalType::toString(hval[i], lval[i], sval[i]);
-        double fval = stod(strVecVal);
-        rdata[i] = static_cast<TR>(fval);
+        rdata[i] = decimalToFloat<TR>(hval[i], lval[i], sval[i]);
       }
     }
   }
@@ -472,21 +526,19 @@
         auto index = (*sel)[i];
         rnull[index] = nulls[index];
         if (!rnull[index]) {
-          snprintf(buffer, sizeof(buffer), "%.*g", DBL_DIG, v[index]);
-          DecimalVar decVal = DecimalType::fromString(buffer);
-          rLowbit[index] = decVal.lowbits;
-          rHighbit[index] = decVal.highbits;
-          rScales[index] = decVal.scale;
+          DecimalVar decValtmp = floatToDecimal(v[index]);
+          rLowbit[index] = decValtmp.lowbits;
+          rHighbit[index] = decValtmp.highbits;
+          rScales[index] = decValtmp.scale;
         }
       }
     } else {
       for (uint64_t i = 0; i < sz; ++i) {
         auto index = (*sel)[i];
-        snprintf(buffer, sizeof(buffer), "%.*g", DBL_DIG, v[index]);
-        DecimalVar decVal = DecimalType::fromString(buffer);
-        rLowbit[index] = decVal.lowbits;
-        rHighbit[index] = decVal.highbits;
-        rScales[index] = decVal.scale;
+        DecimalVar decValtmp = floatToDecimal(v[index]);
+        rLowbit[index] = decValtmp.lowbits;
+        rHighbit[index] = decValtmp.highbits;
+        rScales[index] = decValtmp.scale;
       }
     }
   } else {
@@ -495,20 +547,18 @@
       for (uint64_t i = 0; i < sz; ++i) {
         rnull[i] = nulls[i];
         if (!rnull[i]) {
-          snprintf(buffer, sizeof(buffer), "%.*g", DBL_DIG, v[i]);
-          DecimalVar decVal = DecimalType::fromString(buffer);
-          rLowbit[i] = decVal.lowbits;
-          rHighbit[i] = decVal.highbits;
-          rScales[i] = decVal.scale;
+          DecimalVar decValtmp = floatToDecimal(v[i]);
+          rLowbit[i] = decValtmp.lowbits;
+          rHighbit[i] = decValtmp.highbits;
+          rScales[i] = decValtmp.scale;
         }
       }
     } else {
       for (uint64_t i = 0; i < sz; ++i) {
-        snprintf(buffer, sizeof(buffer), "%.*g", DBL_DIG, v[i]);
-        DecimalVar decVal = DecimalType::fromString(buffer);
-        rLowbit[i] = decVal.lowbits;
-        rHighbit[i] = decVal.highbits;
-        rScales[i] = decVal.scale;
+        DecimalVar decValtmp = floatToDecimal(v[i]);
+        rLowbit[i] = decValtmp.lowbits;
+        rHighbit[i] = decValtmp.highbits;
+        rScales[i] = decValtmp.scale;
       }
     }
   }