You are viewing a plain text version of this content. The canonical link for it is here.
Posted to codereview@trafodion.apache.org by GitBox <gi...@apache.org> on 2019/03/25 10:46:34 UTC

[GitHub] [trafodion] SuJinpei commented on a change in pull request #1777: [TRAFODION-3262] Insert float to numeric(19, 0) lost precision for some case.

SuJinpei commented on a change in pull request #1777: [TRAFODION-3262] Insert float to numeric(19,0) lost precision for some case.
URL: https://github.com/apache/trafodion/pull/1777#discussion_r268580315
 
 

 ##########
 File path: win-odbc64/odbcclient/drvr35/drvrglobal.cpp
 ##########
 @@ -868,47 +870,48 @@ bool use_gcvt(double number, char* string, short size)
 		return true;
 }
 
+/* double_to_char:
+*  number: the number to be converted to char string.
+*  precision: the number of digits after the decimal point.
+*  string: the buffer to receive a null terminated string result on success.
+*  size: the buffer size of string.
+*
+*  return: true on succeeded, false on failed.
+*/
 bool double_to_char (double number, int precision, char* string, short size)
 {
-    bool rc = false;
-    char format[16] = { '\0' };
-    size_t actualLen = 0;
-
-    // make sure any precision of possible double value can be format to the buf. 
-    char buf[MAX_DOUBLE_TO_CHAR_LEN] = { '\0' };
-
-    // precision should less than size
-    precision = precision < size ? precision : size - 1;
-
-    // precission should be limit to a reasonable range.
-    if ((precision < 0) || (precision >(DBL_MANT_DIG - DBL_MIN_EXP))) {
-        goto fun_exit;
-    }
-
-    // we want to return reasonable value even when caller didn't provide sufficiently buffer. 
-    // here using loop because actualLen may increase even precision decrease when fix-point
-    // notation to exponential notation. for example:
-    // for double d = 12345678.9, the caller only provide size=8.
-    // d will first convert to "1.234568e+07", actualLen == 12. then convert to "1.2e+07".
-    do {
-        if (sprintf(format, "%%.%dlg", precision) < 0) {
-            goto fun_exit;
-        }
-        if ((actualLen = sprintf(buf, format, number)) < 0) {
-            goto fun_exit;
-        }
-        if (size > actualLen) {
-            strcpy(string, buf);
-            rc = true;
-            break;
-        }
-        else {
-            precision -= (actualLen - size + 1);
-        }
-    } while ((precision >= 0));
-
-fun_exit:
-	return rc;
+    char format[16] = { '\0' };
+    size_t actualLen = 0;
+    bool need_reprint = false;
+
+    // make sure any precision of possible double value can be format to the buf.
+    char buf[MAX_DOUBLE_TO_CHAR_LEN] = { '\0' };
+
+    // precission should be limit to a reasonable range.
+    if ((precision < 0) || (precision >(DBL_MANT_DIG - DBL_MIN_EXP)))
 
 Review comment:
   Yes, DBL_MIN_EXP is min binary exponent, but we actually should use this value to compute the max precision.  You can refer to https://en.wikipedia.org/wiki/Double-precision_floating-point_format.  The example is: 
   2^(-1)  -> precision: 1
   2^(-2) -> precision:2
   ...
   2^(-52) -> precision:52
   So the fraction part will generate DB_MANT_DIG  precision.
   The fraction part should multiply 2^(DBL_MIN_EXP) which will generate another DBL_MIN_EXP precision,  so the total max precision is DBL_MANT_DIG - DBL_MIN_EXP.
   

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services