Go to the documentation of this file.00001
00002
00003
00004
00005 #ifndef __FAST_ATOF_H_INCLUDED__
00006 #define __FAST_ATOF_H_INCLUDED__
00007
00008 #include "irrMath.h"
00009 #include "irrString.h"
00010
00011 namespace irr
00012 {
00013 namespace core
00014 {
00016
00017
00018 IRRLICHT_API extern irr::core::stringc LOCALE_DECIMAL_POINTS;
00019
00020
00021 const float fast_atof_table[17] = {
00022 0.f,
00023 0.1f,
00024 0.01f,
00025 0.001f,
00026 0.0001f,
00027 0.00001f,
00028 0.000001f,
00029 0.0000001f,
00030 0.00000001f,
00031 0.000000001f,
00032 0.0000000001f,
00033 0.00000000001f,
00034 0.000000000001f,
00035 0.0000000000001f,
00036 0.00000000000001f,
00037 0.000000000000001f,
00038 0.0000000000000001f
00039 };
00040
00042
00049 inline u32 strtoul10(const char* in, const char** out=0)
00050 {
00051 if (!in)
00052 {
00053 if (out)
00054 *out = in;
00055 return 0;
00056 }
00057
00058 bool overflow=false;
00059 u32 unsignedValue = 0;
00060 while ( ( *in >= '0') && ( *in <= '9' ))
00061 {
00062 const u32 tmp = ( unsignedValue * 10 ) + ( *in - '0' );
00063 if (tmp<unsignedValue)
00064 {
00065 unsignedValue=(u32)0xffffffff;
00066 overflow=true;
00067 }
00068 if (!overflow)
00069 unsignedValue = tmp;
00070 ++in;
00071 }
00072
00073 if (out)
00074 *out = in;
00075
00076 return unsignedValue;
00077 }
00078
00080
00089 inline s32 strtol10(const char* in, const char** out=0)
00090 {
00091 if (!in)
00092 {
00093 if (out)
00094 *out = in;
00095 return 0;
00096 }
00097
00098 const bool negative = ('-' == *in);
00099 if (negative || ('+' == *in))
00100 ++in;
00101
00102 const u32 unsignedValue = strtoul10(in,out);
00103 if (unsignedValue > (u32)INT_MAX)
00104 {
00105 if (negative)
00106 return (s32)INT_MIN;
00107 else
00108 return (s32)INT_MAX;
00109 }
00110 else
00111 {
00112 if (negative)
00113 return -((s32)unsignedValue);
00114 else
00115 return (s32)unsignedValue;
00116 }
00117 }
00118
00120
00125 inline u32 ctoul16(char in)
00126 {
00127 if (in >= '0' && in <= '9')
00128 return in - '0';
00129 else if (in >= 'a' && in <= 'f')
00130 return 10u + in - 'a';
00131 else if (in >= 'A' && in <= 'F')
00132 return 10u + in - 'A';
00133 else
00134 return 0xffffffff;
00135 }
00136
00138
00146 inline u32 strtoul16(const char* in, const char** out=0)
00147 {
00148 if (!in)
00149 {
00150 if (out)
00151 *out = in;
00152 return 0;
00153 }
00154
00155 bool overflow=false;
00156 u32 unsignedValue = 0;
00157 while (true)
00158 {
00159 u32 tmp = 0;
00160 if ((*in >= '0') && (*in <= '9'))
00161 tmp = (unsignedValue << 4u) + (*in - '0');
00162 else if ((*in >= 'A') && (*in <= 'F'))
00163 tmp = (unsignedValue << 4u) + (*in - 'A') + 10;
00164 else if ((*in >= 'a') && (*in <= 'f'))
00165 tmp = (unsignedValue << 4u) + (*in - 'a') + 10;
00166 else
00167 break;
00168 if (tmp<unsignedValue)
00169 {
00170 unsignedValue=(u32)INT_MAX;
00171 overflow=true;
00172 }
00173 if (!overflow)
00174 unsignedValue = tmp;
00175 ++in;
00176 }
00177
00178 if (out)
00179 *out = in;
00180
00181 return unsignedValue;
00182 }
00183
00185
00193 inline u32 strtoul8(const char* in, const char** out=0)
00194 {
00195 if (!in)
00196 {
00197 if (out)
00198 *out = in;
00199 return 0;
00200 }
00201
00202 bool overflow=false;
00203 u32 unsignedValue = 0;
00204 while (true)
00205 {
00206 u32 tmp = 0;
00207 if ((*in >= '0') && (*in <= '7'))
00208 tmp = (unsignedValue << 3u) + (*in - '0');
00209 else
00210 break;
00211 if (tmp<unsignedValue)
00212 {
00213 unsignedValue=(u32)INT_MAX;
00214 overflow=true;
00215 }
00216 if (!overflow)
00217 unsignedValue = tmp;
00218 ++in;
00219 }
00220
00221 if (out)
00222 *out = in;
00223
00224 return unsignedValue;
00225 }
00226
00228
00236 inline u32 strtoul_prefix(const char* in, const char** out=0)
00237 {
00238 if (!in)
00239 {
00240 if (out)
00241 *out = in;
00242 return 0;
00243 }
00244 if ('0'==in[0])
00245 return ('x'==in[1] ? strtoul16(in+2,out) : strtoul8(in+1,out));
00246 return strtoul10(in,out);
00247 }
00248
00250
00258 inline f32 strtof10(const char* in, const char** out = 0)
00259 {
00260 if (!in)
00261 {
00262 if (out)
00263 *out = in;
00264 return 0.f;
00265 }
00266
00267 const u32 MAX_SAFE_U32_VALUE = UINT_MAX / 10 - 10;
00268 u32 intValue = 0;
00269
00270
00271
00272 while ( ( *in >= '0') && ( *in <= '9' ) )
00273 {
00274
00275
00276 if (intValue >= MAX_SAFE_U32_VALUE)
00277 break;
00278
00279 intValue = (intValue * 10) + (*in - '0');
00280 ++in;
00281 }
00282
00283 f32 floatValue = (f32)intValue;
00284
00285
00286
00287 while ( ( *in >= '0') && ( *in <= '9' ) )
00288 {
00289 floatValue = (floatValue * 10.f) + (f32)(*in - '0');
00290 ++in;
00291 if (floatValue > FLT_MAX)
00292 break;
00293 }
00294
00295 if (out)
00296 *out = in;
00297
00298 return floatValue;
00299 }
00300
00302
00309 inline const char* fast_atof_move(const char* in, f32& result)
00310 {
00311
00312
00313 result = 0.f;
00314 if (!in)
00315 return 0;
00316
00317 const bool negative = ('-' == *in);
00318 if (negative || ('+'==*in))
00319 ++in;
00320
00321 f32 value = strtof10(in, &in);
00322
00323 if ( LOCALE_DECIMAL_POINTS.findFirst(*in) >= 0 )
00324 {
00325 const char* afterDecimal = ++in;
00326 const f32 decimal = strtof10(in, &afterDecimal);
00327 value += decimal * fast_atof_table[afterDecimal - in];
00328 in = afterDecimal;
00329 }
00330
00331 if ('e' == *in || 'E' == *in)
00332 {
00333 ++in;
00334
00335
00336
00337 value *= powf(10.f, (f32)strtol10(in, &in));
00338 }
00339
00340 result = negative?-value:value;
00341 return in;
00342 }
00343
00345
00350 inline float fast_atof(const char* floatAsString, const char** out=0)
00351 {
00352 float ret;
00353 if (out)
00354 *out=fast_atof_move(floatAsString, ret);
00355 else
00356 fast_atof_move(floatAsString, ret);
00357 return ret;
00358 }
00359
00360 }
00361 }
00362
00363 #endif
00364