#include "my_base.h"#include "m_ctype.h"Include dependency graph for strtod.c:

Go to the source code of this file.
Defines | |
| #define | MAX_DBL_EXP 308 |
| #define | MAX_RESULT_FOR_MAX_EXP 1.79769313486232 |
Functions | |
| double | my_strtod (const char *str, char **end_ptr, int *error) |
| double | my_atof (const char *nptr) |
Variables | |
| static double | scaler10 [] |
| static double | scaler1 [] |
| double my_atof | ( | const char * | nptr | ) |
| double my_strtod | ( | const char * | str, | |
| char ** | end_ptr, | |||
| int * | error | |||
| ) |
Definition at line 56 of file strtod.c.
References DBL_MAX, EOVERFLOW, isinf, MAX_DBL_EXP, MAX_RESULT_FOR_MAX_EXP, my_charset_latin1, my_isdigit, my_isspace, scaler1, and scaler10.
00057 { 00058 double result= 0.0; 00059 uint negative= 0, ndigits, dec_digits= 0, neg_exp= 0; 00060 int exp= 0, digits_after_dec_point= 0; 00061 const char *old_str, *end= *end_ptr, *start_of_number; 00062 char next_char; 00063 my_bool overflow=0; 00064 00065 *error= 0; 00066 if (str >= end) 00067 goto done; 00068 00069 while (my_isspace(&my_charset_latin1, *str)) 00070 { 00071 if (++str == end) 00072 goto done; 00073 } 00074 00075 start_of_number= str; 00076 if ((negative= (*str == '-')) || *str=='+') 00077 { 00078 if (++str == end) 00079 goto done; /* Could be changed to error */ 00080 } 00081 00082 /* Skip pre-zero for easier calculation of overflows */ 00083 while (*str == '0') 00084 { 00085 if (++str == end) 00086 goto done; 00087 start_of_number= 0; /* Found digit */ 00088 } 00089 00090 old_str= str; 00091 while ((next_char= *str) >= '0' && next_char <= '9') 00092 { 00093 result= result*10.0 + (next_char - '0'); 00094 if (++str == end) 00095 { 00096 next_char= 0; /* Found end of string */ 00097 break; 00098 } 00099 start_of_number= 0; /* Found digit */ 00100 } 00101 ndigits= (uint) (str-old_str); 00102 00103 if (next_char == '.' && str < end-1) 00104 { 00105 /* 00106 Continue to add numbers after decimal point to the result, as if there 00107 was no decimal point. We will later (in the exponent handling) shift 00108 the number down with the required number of fractions. We do it this 00109 way to be able to get maximum precision for numbers like 123.45E+02, 00110 which are normal for some ODBC applications. 00111 */ 00112 old_str= ++str; 00113 while (my_isdigit(&my_charset_latin1, (next_char= *str))) 00114 { 00115 result= result*10.0 + (next_char - '0'); 00116 digits_after_dec_point++; 00117 if (++str == end) 00118 { 00119 next_char= 0; 00120 break; 00121 } 00122 } 00123 /* If we found just '+.' or '.' then point at first character */ 00124 if (!(dec_digits= (uint) (str-old_str)) && start_of_number) 00125 str= start_of_number; /* Point at '+' or '.' */ 00126 } 00127 if ((next_char == 'e' || next_char == 'E') && 00128 dec_digits + ndigits != 0 && str < end-1) 00129 { 00130 const char *old_str= str++; 00131 00132 if ((neg_exp= (*str == '-')) || *str == '+') 00133 str++; 00134 00135 if (str == end || !my_isdigit(&my_charset_latin1, *str)) 00136 str= old_str; 00137 else 00138 { 00139 do 00140 { 00141 if (exp < 9999) /* prot. against exp overfl. */ 00142 exp= exp*10 + (*str - '0'); 00143 str++; 00144 } while (str < end && my_isdigit(&my_charset_latin1, *str)); 00145 } 00146 } 00147 if ((exp= (neg_exp ? exp + digits_after_dec_point : 00148 exp - digits_after_dec_point))) 00149 { 00150 double scaler; 00151 if (exp < 0) 00152 { 00153 exp= -exp; 00154 neg_exp= 1; /* neg_exp was 0 before */ 00155 } 00156 if (exp + ndigits >= MAX_DBL_EXP + 1 && result) 00157 { 00158 /* 00159 This is not 100 % as we actually will give an owerflow for 00160 17E307 but not for 1.7E308 but lets cut some corners to make life 00161 simpler 00162 */ 00163 if (exp + ndigits > MAX_DBL_EXP + 1 || 00164 result >= MAX_RESULT_FOR_MAX_EXP) 00165 { 00166 if (neg_exp) 00167 result= 0.0; 00168 else 00169 overflow= 1; 00170 goto done; 00171 } 00172 } 00173 scaler= 1.0; 00174 while (exp >= 100) 00175 { 00176 scaler*= 1.0e100; 00177 exp-= 100; 00178 } 00179 scaler*= scaler10[exp/10]*scaler1[exp%10]; 00180 if (neg_exp) 00181 result/= scaler; 00182 else 00183 result*= scaler; 00184 } 00185 00186 done: 00187 *end_ptr= (char*) str; /* end of number */ 00188 00189 if (overflow || isinf(result)) 00190 { 00191 result= DBL_MAX; 00192 *error= EOVERFLOW; 00193 } 00194 00195 return negative ? -result : result; 00196 }
double scaler1[] [static] |
double scaler10[] [static] |
1.4.7

