MySQL 8.4.0
Source Code Documentation
dtoa.h File Reference
#include <cfloat>
#include <cstddef>
#include "mysql/strings/api.h"

Go to the source code of this file.

Macros

#define MAX_DECPT_FOR_F_FORMAT   DBL_DIG
 
#define MY_GCVT_MAX_FIELD_WIDTH    (DBL_DIG + 4 + std::max(5, MAX_DECPT_FOR_F_FORMAT))
 

Enumerations

enum  my_gcvt_arg_type { MY_GCVT_ARG_FLOAT , MY_GCVT_ARG_DOUBLE }
 

Functions

MYSQL_STRINGS_EXPORT double my_strtod (const char *str, const char **end, int *error)
 Converts string to double (string does not have to be zero-terminated) More...
 
MYSQL_STRINGS_EXPORT size_t my_fcvt (double x, int precision, char *to, bool *error)
 Converts a given floating point number to a zero-terminated string representation using the 'f' format. More...
 
MYSQL_STRINGS_EXPORT size_t my_fcvt_compact (double x, char *to, bool *error)
 Converts a given floating point number to a zero-terminated string representation using the 'f' format. More...
 
MYSQL_STRINGS_EXPORT size_t my_gcvt (double x, my_gcvt_arg_type type, int width, char *to, bool *error)
 Converts a given floating point number to a zero-terminated string representation with a given field width using the 'e' format (aka scientific notation) or the 'f' one. More...
 

Variables

static constexpr int DECIMAL_MAX_SCALE {30}
 
static constexpr int DECIMAL_NOT_SPECIFIED {DECIMAL_MAX_SCALE + 1}
 
static constexpr int FLOATING_POINT_BUFFER {311 + DECIMAL_NOT_SPECIFIED}
 

Macro Definition Documentation

◆ MAX_DECPT_FOR_F_FORMAT

#define MAX_DECPT_FOR_F_FORMAT   DBL_DIG

◆ MY_GCVT_MAX_FIELD_WIDTH

#define MY_GCVT_MAX_FIELD_WIDTH    (DBL_DIG + 4 + std::max(5, MAX_DECPT_FOR_F_FORMAT))

Enumeration Type Documentation

◆ my_gcvt_arg_type

Enumerator
MY_GCVT_ARG_FLOAT 
MY_GCVT_ARG_DOUBLE 

Function Documentation

◆ my_fcvt()

MYSQL_STRINGS_EXPORT size_t my_fcvt ( double  x,
int  precision,
char *  to,
bool *  error 
)

Converts a given floating point number to a zero-terminated string representation using the 'f' format.

This function is a wrapper around dtoa() to do the same as sprintf(to, "%-.*f", precision, x), though the conversion is usually more precise. The only difference is in handling [-,+]infinity and nan values, in which case we print '0\0' to the output string and indicate an overflow.

Parameters
xthe input floating point number.
precisionthe number of digits after the decimal point. All properties of sprintf() apply:
  • if the number of significant digits after the decimal point is less than precision, the resulting string is right-padded with zeros
  • if the precision is 0, no decimal point appears
  • if a decimal point appears, at least one digit appears before it
topointer to the output buffer. The longest string which my_fcvt() can return is FLOATING_POINT_BUFFER bytes (including the terminating '\0').
errorif not NULL, points to a location where the status of conversion is stored upon return. false successful conversion true the input number is [-,+]infinity or nan. The output string in this case is always '0'.
Returns
number of written characters (excluding terminating '\0')

◆ my_fcvt_compact()

MYSQL_STRINGS_EXPORT size_t my_fcvt_compact ( double  x,
char *  to,
bool *  error 
)

Converts a given floating point number to a zero-terminated string representation using the 'f' format.

This function is a wrapper around dtoa() to do almost the same as sprintf(to, "%-.*f", precision, x), though the conversion is usually more precise. The only difference is in handling [-,+]infinity and nan values, in which case we print '0\0' to the output string and indicate an overflow.

The string always contains the minimum number of digits necessary to reproduce the same binary double value if the string is parsed back to a double value.

Parameters
xthe input floating point number.
topointer to the output buffer. The longest string which my_fcvt() can return is FLOATING_POINT_BUFFER bytes (including the terminating '\0').
errorif not NULL, points to a location where the status of conversion is stored upon return. false successful conversion true the input number is [-,+]infinity or nan. The output string in this case is always '0'.
Returns
number of written characters (excluding terminating '\0')

◆ my_gcvt()

MYSQL_STRINGS_EXPORT size_t my_gcvt ( double  x,
my_gcvt_arg_type  type,
int  width,
char *  to,
bool *  error 
)

Converts a given floating point number to a zero-terminated string representation with a given field width using the 'e' format (aka scientific notation) or the 'f' one.

The format is chosen automatically to provide the most number of significant digits (and thus, precision) with a given field width. In many cases, the result is similar to that of sprintf(to, "%g", x) with a few notable differences:

  • the conversion is usually more precise than C library functions.
  • there is no 'precision' argument. instead, we specify the number of characters available for conversion (i.e. a field width).
  • the result never exceeds the specified field width. If the field is too short to contain even a rounded decimal representation, my_gcvt() indicates overflow and truncates the output string to the specified width.
  • float-type arguments are handled differently than double ones. For a float input number (i.e. when the 'type' argument is MY_GCVT_ARG_FLOAT) we deliberately limit the precision of conversion by FLT_DIG digits to avoid garbage past the significant digits.
  • unlike sprintf(), in cases where the 'e' format is preferred, we don't zero-pad the exponent to save space for significant digits. The '+' sign for a positive exponent does not appear for the same reason.
Parameters
xthe input floating point number.
typeis either MY_GCVT_ARG_FLOAT or MY_GCVT_ARG_DOUBLE. Specifies the type of the input number (see notes above).
widthfield width in characters. The minimal field width to hold any number representation (albeit rounded) is 7 characters ("-Ne-NNN").
topointer to the output buffer. The result is always zero-terminated, and the longest returned string is thus 'width + 1' bytes.
errorif not NULL, points to a location where the status of conversion is stored upon return. false successful conversion true the input number is [-,+]infinity or nan. The output string in this case is always '0'.
Returns
number of written characters (excluding terminating '\0')

my_gcvt(-9e-3, ..., 4, ...); my_gcvt(-9e-3, ..., 2, ...); my_gcvt(1.87e-3, ..., 4, ...); my_gcvt(55, ..., 1, ...);

We do our best to minimize such cases by:

  • passing to dtoa() the field width as the number of significant digits
  • removing the sign of the number early (and decreasing the width before passing it to dtoa())
  • choosing the proper format to preserve the most number of significant digits.

◆ my_strtod()

MYSQL_STRINGS_EXPORT double my_strtod ( const char *  str,
const char **  end,
int *  error 
)

Converts string to double (string does not have to be zero-terminated)

This is a wrapper around dtoa's version of strtod().

Parameters
strinput string
endaddress of a pointer to the first character after the input string. Upon return the pointer is set to point to the first rejected character.
errorUpon return is set to EOVERFLOW in case of underflow or overflow.
Returns
The resulting double value. In case of underflow, 0.0 is returned. In case overflow, signed DBL_MAX is returned.

Variable Documentation

◆ DECIMAL_MAX_SCALE

constexpr int DECIMAL_MAX_SCALE {30}
staticconstexpr

◆ DECIMAL_NOT_SPECIFIED

constexpr int DECIMAL_NOT_SPECIFIED {DECIMAL_MAX_SCALE + 1}
staticconstexpr

◆ FLOATING_POINT_BUFFER

constexpr int FLOATING_POINT_BUFFER {311 + DECIMAL_NOT_SPECIFIED}
staticconstexpr