summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAlexey Kopytov <Alexey.Kopytov@Sun.com>2009-12-22 19:23:13 +0300
committerAlexey Kopytov <Alexey.Kopytov@Sun.com>2009-12-22 19:23:13 +0300
commitf02525be8346b7426f1640fb168a7451d38b1641 (patch)
tree40437c602d2a9ddaa03a54742cec4884f0974253 /include
parent5bce1e06429c3d58457051f0c439f130609df375 (diff)
downloadmariadb-git-f02525be8346b7426f1640fb168a7451d38b1641.tar.gz
Backport of WL #2934: Make/find library for doing float/double
to string conversions and vice versa" Initial import of the dtoa.c code and custom wrappers around it to allow its usage from the server code. Conversion of FLOAT/DOUBLE values to DECIMAL ones or strings and vice versa has been significantly reworked. As the new algoritms are more precise than the older ones, results of such conversions may not always match those obtained from older server versions. This in turn may break compatibility for some applications. This patch also fixes the following bugs: - bug #12860 "Difference in zero padding of exponent between Unix and Windows" - bug #21497 "DOUBLE truncated to unusable value" - bug #26788 "mysqld (debug) aborts when inserting specific numbers into char fields" - bug #24541 "Data truncated..." on decimal type columns without any good reason"
Diffstat (limited to 'include')
-rw-r--r--include/m_string.h37
1 files changed, 34 insertions, 3 deletions
diff --git a/include/m_string.h b/include/m_string.h
index a6a36f32ca4..45801ff85b7 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -92,9 +92,6 @@ extern char *stpcpy(char *, const char *); /* For AIX with gcc 2.95.3 */
extern char NEAR _dig_vec_upper[];
extern char NEAR _dig_vec_lower[];
-/* Defined in strtod.c */
-extern const double log_10[309];
-
#ifdef BAD_STRING_COMPILER
#define strmov(A,B) (memccpy(A,B,0,INT_MAX)-1)
#else
@@ -199,8 +196,42 @@ extern char *strstr(const char *, const char *);
extern int is_prefix(const char *, const char *);
/* Conversion routines */
+typedef enum {
+ MY_GCVT_ARG_FLOAT,
+ MY_GCVT_ARG_DOUBLE
+} my_gcvt_arg_type;
+
double my_strtod(const char *str, char **end, int *error);
double my_atof(const char *nptr);
+size_t my_fcvt(double x, int precision, char *to, my_bool *error);
+size_t my_gcvt(double x, my_gcvt_arg_type type, int width, char *to,
+ my_bool *error);
+
+#define NOT_FIXED_DEC 31
+
+/*
+ The longest string my_fcvt can return is 311 + "precision" bytes.
+ Here we assume that we never cal my_fcvt() with precision >= NOT_FIXED_DEC
+ (+ 1 byte for the terminating '\0').
+*/
+#define FLOATING_POINT_BUFFER (311 + NOT_FIXED_DEC)
+
+/*
+ We want to use the 'e' format in some cases even if we have enough space
+ for the 'f' one just to mimic sprintf("%.15g") behavior for large integers,
+ and to improve it for numbers < 10^(-4).
+ That is, for |x| < 1 we require |x| >= 10^(-15), and for |x| > 1 we require
+ it to be integer and be <= 10^DBL_DIG for the 'f' format to be used.
+ We don't lose precision, but make cases like "1e200" or "0.00001" look nicer.
+*/
+#define MAX_DECPT_FOR_F_FORMAT DBL_DIG
+
+/*
+ The maximum possible field width for my_gcvt() conversion.
+ (DBL_DIG + 2) significant digits + sign + "." + ("e-NNN" or
+ MAX_DECPT_FOR_F_FORMAT zeros for cases when |x|<1 and the 'f' format is used).
+*/
+#define MY_GCVT_MAX_FIELD_WIDTH (DBL_DIG + 4 + max(5, MAX_DECPT_FOR_F_FORMAT)) \
extern char *llstr(longlong value,char *buff);
extern char *ullstr(longlong value,char *buff);