Home | Namespaces | Hierarchy | Alphabetical List | Class list | Files | Namespace Members | Class members | File members | Tutorials
fast_atof.h
Go to the documentation of this file.
1 // Copyright (C) 2002-2010 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_A_TO_F_H_INCLUDED__
6 #define __FAST_A_TO_F_H_INCLUDED__
7 
8 #include "irrMath.h"
9 
10 namespace irr
11 {
12 namespace core
13 {
14 
15 // we write [17] here instead of [] to work around a swig bug
16 const float fast_atof_table[17] = {
17  0.f,
18  0.1f,
19  0.01f,
20  0.001f,
21  0.0001f,
22  0.00001f,
23  0.000001f,
24  0.0000001f,
25  0.00000001f,
26  0.000000001f,
27  0.0000000001f,
28  0.00000000001f,
29  0.000000000001f,
30  0.0000000000001f,
31  0.00000000000001f,
32  0.000000000000001f,
33  0.0000000000000001f
34 };
35 
44 inline s32 strtol10(const char* in, const char** out=0)
45 {
46  if(!in)
47  return 0;
48 
49  bool negative = false;
50  if('-' == *in)
51  {
52  negative = true;
53  ++in;
54  }
55  else if('+' == *in)
56  ++in;
57 
58  u32 unsignedValue = 0;
59 
60  while ( ( *in >= '0') && ( *in <= '9' ))
61  {
62  unsignedValue = ( unsignedValue * 10 ) + ( *in - '0' );
63  ++in;
64 
65  if(unsignedValue > (u32)INT_MAX)
66  {
67  unsignedValue = (u32)INT_MAX;
68  break;
69  }
70  }
71  if (out)
72  *out = in;
73 
74  if(negative)
75  return -((s32)unsignedValue);
76  else
77  return (s32)unsignedValue;
78 }
79 
86 inline f32 strtof10(const char* in, const char * * out = 0)
87 {
88  if(out)
89  *out = in;
90 
91  if(!in)
92  return 0.f;
93 
94  static const u32 MAX_SAFE_U32_VALUE = UINT_MAX / 10 - 10;
95  f32 floatValue = 0.f;
96  u32 intValue = 0;
97 
98  // Use integer arithmetic for as long as possible, for speed
99  // and precision.
100  while ( ( *in >= '0') && ( *in <= '9' ) )
101  {
102  // If it looks like we're going to overflow, bail out
103  // now and start using floating point.
104  if(intValue >= MAX_SAFE_U32_VALUE)
105  break;
106 
107  intValue = ( intValue * 10) + ( *in - '0' );
108  ++in;
109  }
110 
111  floatValue = (f32)intValue;
112 
113  // If there are any digits left to parse, then we need to use
114  // floating point arithmetic from here.
115  while ( ( *in >= '0') && ( *in <= '9' ) )
116  {
117  floatValue = ( floatValue * 10.f ) + (f32)( *in - '0' );
118  ++in;
119  if(floatValue > FLT_MAX) // Just give up.
120  break;
121  }
122 
123  if(out)
124  *out = in;
125 
126  return floatValue;
127 }
128 
136 inline const char* fast_atof_move( const char * in, f32 & out)
137 {
138  // Please run this regression test when making any modifications to this function:
139  // https://sourceforge.net/tracker/download.php?group_id=74339&atid=540676&file_id=298968&aid=1865300
140 
141  out = 0.f;
142  if(!in)
143  return 0;
144 
145  bool negative = false;
146  if(*in == '-')
147  {
148  negative = true;
149  ++in;
150  }
151 
152  f32 value = strtof10 ( in, &in );
153 
154  if (*in == '.')
155  {
156  ++in;
157 
158  const char * afterDecimal = in;
159  f32 decimal = strtof10 ( in, &afterDecimal );
160  decimal *= fast_atof_table[afterDecimal - in];
161 
162  value += decimal;
163 
164  in = afterDecimal;
165  }
166 
167  if ('e' == *in || 'E' == *in)
168  {
169  ++in;
170  // Assume that the exponent is a whole number.
171  // strtol10() will deal with both + and - signs,
172  // but cast to (f32) to prevent overflow at FLT_MAX
173  value *= (f32)pow(10.0f, (f32)strtol10(in, &in));
174  }
175 
176  if(negative)
177  out = -value;
178  else
179  out = value;
180 
181  return in;
182 }
183 
186 inline float fast_atof(const char* floatAsString)
187 {
188  float ret;
189  fast_atof_move(floatAsString, ret);
190  return ret;
191 }
192 
193 } // end namespace core
194 } // end namespace irr
195 
196 #endif
197 

The Irrlicht Engine
The Irrlicht Engine Documentation © 2003-2010 by Nikolaus Gebhardt. Generated on Fri Mar 21 2014 04:40:16 by Doxygen (1.8.1.2)