Irrlicht 3D Engine
 
Loading...
Searching...
No Matches
fast_atof.h
Go to the documentation of this file.
1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine" and the "irrXML" project.
3// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
4
5#ifndef __FAST_ATOF_H_INCLUDED__
6#define __FAST_ATOF_H_INCLUDED__
7
8#include "irrMath.h"
9#include "irrString.h"
10
11namespace irr
12{
13namespace core
14{
16 // TODO: This should probably also be used in irr::core::string, but the float-to-string code
17 // used there has to be rewritten first.
19
20#define IRR_ATOF_TABLE_SIZE 17
21// we write [IRR_ATOF_TABLE_SIZE] here instead of [] to work around a swig bug
22const float fast_atof_table[17] = {
23 0.f,
24 0.1f,
25 0.01f,
26 0.001f,
27 0.0001f,
28 0.00001f,
29 0.000001f,
30 0.0000001f,
31 0.00000001f,
32 0.000000001f,
33 0.0000000001f,
34 0.00000000001f,
35 0.000000000001f,
36 0.0000000000001f,
37 0.00000000000001f,
38 0.000000000000001f,
39 0.0000000000000001f
40};
41
43
50inline u32 strtoul10(const char* in, const char** out=0)
51{
52 if (!in)
53 {
54 if (out)
55 *out = in;
56 return 0;
57 }
58
59 bool overflow=false;
61 while ( ( *in >= '0') && ( *in <= '9' ))
62 {
63 const u32 tmp = ( unsignedValue * 10 ) + ( *in - '0' );
65 {
66 unsignedValue=(u32)0xffffffff;
67 overflow=true;
68 }
69 if (!overflow)
71 ++in;
72 }
73
74 if (out)
75 *out = in;
76
77 return unsignedValue;
78}
79
81
90inline s32 strtol10(const char* in, const char** out=0)
91{
92 if (!in)
93 {
94 if (out)
95 *out = in;
96 return 0;
97 }
98
99 const bool negative = ('-' == *in);
100 if (negative || ('+' == *in))
101 ++in;
102
105 {
106 if (negative)
107 return (s32)INT_MIN;
108 else
109 return (s32)INT_MAX;
110 }
111 else
112 {
113 if (negative)
114 return -((s32)unsignedValue);
115 else
116 return (s32)unsignedValue;
117 }
118}
119
121
126inline u32 ctoul16(char in)
127{
128 if (in >= '0' && in <= '9')
129 return in - '0';
130 else if (in >= 'a' && in <= 'f')
131 return 10u + in - 'a';
132 else if (in >= 'A' && in <= 'F')
133 return 10u + in - 'A';
134 else
135 return 0xffffffff;
136}
137
139
147inline u32 strtoul16(const char* in, const char** out=0)
148{
149 if (!in)
150 {
151 if (out)
152 *out = in;
153 return 0;
154 }
155
156 bool overflow=false;
157 u32 unsignedValue = 0;
158 while (true)
159 {
160 u32 tmp = 0;
161 if ((*in >= '0') && (*in <= '9'))
162 tmp = (unsignedValue << 4u) + (*in - '0');
163 else if ((*in >= 'A') && (*in <= 'F'))
164 tmp = (unsignedValue << 4u) + (*in - 'A') + 10;
165 else if ((*in >= 'a') && (*in <= 'f'))
166 tmp = (unsignedValue << 4u) + (*in - 'a') + 10;
167 else
168 break;
169 if (tmp<unsignedValue)
170 {
172 overflow=true;
173 }
174 if (!overflow)
176 ++in;
177 }
178
179 if (out)
180 *out = in;
181
182 return unsignedValue;
183}
184
186
194inline u32 strtoul8(const char* in, const char** out=0)
195{
196 if (!in)
197 {
198 if (out)
199 *out = in;
200 return 0;
201 }
202
203 bool overflow=false;
204 u32 unsignedValue = 0;
205 while (true)
206 {
207 u32 tmp = 0;
208 if ((*in >= '0') && (*in <= '7'))
209 tmp = (unsignedValue << 3u) + (*in - '0');
210 else
211 break;
212 if (tmp<unsignedValue)
213 {
215 overflow=true;
216 }
217 if (!overflow)
219 ++in;
220 }
221
222 if (out)
223 *out = in;
224
225 return unsignedValue;
226}
227
229
237inline u32 strtoul_prefix(const char* in, const char** out=0)
238{
239 if (!in)
240 {
241 if (out)
242 *out = in;
243 return 0;
244 }
245 if ('0'==in[0])
246 return ('x'==in[1] ? strtoul16(in+2,out) : strtoul8(in+1,out));
247 return strtoul10(in,out);
248}
249
251
259inline f32 strtof10(const char* in, const char** out = 0)
260{
261 if (!in)
262 {
263 if (out)
264 *out = in;
265 return 0.f;
266 }
267
268 const u32 MAX_SAFE_U32_VALUE = UINT_MAX / 10 - 10;
269 u32 intValue = 0;
270
271 // Use integer arithmetic for as long as possible, for speed
272 // and precision.
273 while ( ( *in >= '0') && ( *in <= '9' ) )
274 {
275 // If it looks like we're going to overflow, bail out
276 // now and start using floating point.
278 break;
279
280 intValue = (intValue * 10) + (*in - '0');
281 ++in;
282 }
283
285
286 // If there are any digits left to parse, then we need to use
287 // floating point arithmetic from here.
288 while ( ( *in >= '0') && ( *in <= '9' ) )
289 {
290 floatValue = (floatValue * 10.f) + (f32)(*in - '0');
291 ++in;
292 if (floatValue > FLT_MAX) // Just give up.
293 break;
294 }
295
296 if (out)
297 *out = in;
298
299 return floatValue;
300}
301
303
310inline const char* fast_atof_move(const char* in, f32& result)
311{
312 // Please run the regression test when making any modifications to this function.
313
314 result = 0.f;
315 if (!in)
316 return 0;
317
318 const bool negative = ('-' == *in);
319 if (negative || ('+'==*in))
320 ++in;
321
322 f32 value = strtof10(in, &in);
323
324 if ( LOCALE_DECIMAL_POINTS.findFirst(*in) >= 0 )
325 {
326 const char* afterDecimal = ++in;
328 size_t numDecimals = afterDecimal - in;
330 {
332 }
333 else
334 {
335 value += decimal * (f32)pow(10.f, -(float)numDecimals);
336 }
338 }
339
340 if ('e' == *in || 'E' == *in)
341 {
342 ++in;
343 // Assume that the exponent is a whole number.
344 // strtol10() will deal with both + and - signs,
345 // but calculate as f32 to prevent overflow at FLT_MAX
346 // Using pow with float cast instead of powf as otherwise accuracy decreases.
347 value *= (f32)pow(10.f, (f32)strtol10(in, &in));
348 }
349
351 return in;
352}
353
355
360inline float fast_atof(const char* floatAsString, const char** out=0)
361{
362 float ret;
363 if (out)
365 else
367 return ret;
368}
369
370} // end namespace core
371} // end namespace irr
372
373#endif
374
#define IRRLICHT_API
Set FPU settings.
Axis aligned bounding box in 3d dimensional space.
Definition aabbox3d.h:22
#define IRR_ATOF_TABLE_SIZE
Definition fast_atof.h:20
#define FLT_MAX
Definition irrMath.h:31
u32 strtoul8(const char *in, const char **out=0)
Convert a simple string of base 8 digits into an unsigned 32 bit integer.
Definition fast_atof.h:194
f32 strtof10(const char *in, const char **out=0)
Converts a sequence of digits into a whole positive floating point value.
Definition fast_atof.h:259
const char * fast_atof_move(const char *in, f32 &result)
Provides a fast function for converting a string into a float.
Definition fast_atof.h:310
s32 strtol10(const char *in, const char **out=0)
Convert a simple string of base 10 digits into a signed 32 bit integer.
Definition fast_atof.h:90
u32 ctoul16(char in)
Convert a hex-encoded character to an unsigned integer.
Definition fast_atof.h:126
u32 strtoul16(const char *in, const char **out=0)
Convert a simple string of base 16 digits into an unsigned 32 bit integer.
Definition fast_atof.h:147
IRRLICHT_API irr::core::stringc LOCALE_DECIMAL_POINTS
Selection of characters which count as decimal point in fast_atof.
u32 strtoul_prefix(const char *in, const char **out=0)
Convert a C-style prefixed string (hex, oct, integer) into an unsigned 32 bit integer.
Definition fast_atof.h:237
const float fast_atof_table[17]
Definition fast_atof.h:22
u32 strtoul10(const char *in, const char **out=0)
Convert a simple string of base 10 digits into an unsigned 32 bit integer.
Definition fast_atof.h:50
float fast_atof(const char *floatAsString, const char **out=0)
Convert a string to a floating point number.
Definition fast_atof.h:360
Everything in the Irrlicht Engine can be found in this namespace.
Definition aabbox3d.h:13
float f32
32 bit floating point variable.
Definition irrTypes.h:104
unsigned int u32
32 bit unsigned variable.
Definition irrTypes.h:58
signed int s32
32 bit signed variable.
Definition irrTypes.h:66