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.

    00001 // Copyright (C) 2002-2010 Nikolaus Gebhardt
    00002 // This file is part of the "Irrlicht Engine" and the "irrXML" project.
    00003 // For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
    00004
    00005 #ifndef __FAST_A_TO_F_H_INCLUDED__
    00006 #define __FAST_A_TO_F_H_INCLUDED__
    00007
    00008 #include "irrMath.h"
    00009
    00010 namespace irr
    00011 {
    00012 namespace core
    00013 {
    00014
    00015 // we write [17] here instead of [] to work around a swig bug
    00016 const float fast_atof_table[17] = {
    00017         0.f,
    00018         0.1f,
    00019         0.01f,
    00020         0.001f,
    00021         0.0001f,
    00022         0.00001f,
    00023         0.000001f,
    00024         0.0000001f,
    00025         0.00000001f,
    00026         0.000000001f,
    00027         0.0000000001f,
    00028         0.00000000001f,
    00029         0.000000000001f,
    00030         0.0000000000001f,
    00031         0.00000000000001f,
    00032         0.000000000000001f,
    00033         0.0000000000000001f
    00034 };
    00035
    00044 inline s32 strtol10(const char* in, const char** out=0)
    00045 {
    00046         if(!in)
    00047                 return 0;
    00048
    00049         bool negative = false;
    00050         if('-' == *in)
    00051         {
    00052                 negative = true;
    00053                 ++in;
    00054         }
    00055         else if('+' == *in)
    00056                 ++in;
    00057
    00058         u32 unsignedValue = 0;
    00059
    00060         while ( ( *in >= '0') && ( *in <= '9' ))
    00061         {
    00062                 unsignedValue = ( unsignedValue * 10 ) + ( *in - '0' );
    00063                 ++in;
    00064
    00065                 if(unsignedValue > (u32)INT_MAX)
    00066                 {
    00067                         unsignedValue = (u32)INT_MAX;
    00068                         break;
    00069                 }
    00070         }
    00071         if (out)
    00072                 *out = in;
    00073
    00074         if(negative)
    00075                 return -((s32)unsignedValue);
    00076         else
    00077                 return (s32)unsignedValue;
    00078 }
    00079
    00086 inline f32 strtof10(const char* in, const char * * out = 0)
    00087 {
    00088         if(out)
    00089                 *out = in;
    00090
    00091         if(!in)
    00092                 return 0.f;
    00093
    00094         static const u32 MAX_SAFE_U32_VALUE = UINT_MAX / 10 - 10;
    00095         f32 floatValue = 0.f;
    00096         u32 intValue = 0;
    00097
    00098         // Use integer arithmetic for as long as possible, for speed
    00099         // and precision.
    00100         while ( ( *in >= '0') && ( *in <= '9' ) )
    00101         {
    00102                 // If it looks like we're going to overflow, bail out
    00103                 // now and start using floating point.
    00104                 if(intValue >= MAX_SAFE_U32_VALUE)
    00105                         break;
    00106
    00107                 intValue = ( intValue * 10) + ( *in - '0' );
    00108                 ++in;
    00109         }
    00110
    00111         floatValue = (f32)intValue;
    00112
    00113         // If there are any digits left to parse, then we need to use
    00114         // floating point arithmetic from here.
    00115         while ( ( *in >= '0') && ( *in <= '9' ) )
    00116         {
    00117                 floatValue = ( floatValue * 10.f ) + (f32)( *in - '0' );
    00118                 ++in;
    00119                 if(floatValue > FLT_MAX) // Just give up.
    00120                         break;
    00121         }
    00122
    00123         if(out)
    00124                 *out = in;
    00125
    00126         return floatValue;
    00127 }
    00128
    00136 inline const char* fast_atof_move( const char * in, f32 & out)
    00137 {
    00138         // Please run this regression test when making any modifications to this function:
    00139         // https://sourceforge.net/tracker/download.php?group_id=74339&atid=540676&file_id=298968&aid=1865300
    00140
    00141         out = 0.f;
    00142         if(!in)
    00143                 return 0;
    00144
    00145         bool negative = false;
    00146         if(*in == '-')
    00147         {
    00148                 negative = true;
    00149                 ++in;
    00150         }
    00151
    00152         f32 value = strtof10 ( in, &in );
    00153
    00154         if (*in == '.')
    00155         {
    00156                 ++in;
    00157
    00158                 const char * afterDecimal = in;
    00159                 f32 decimal = strtof10 ( in, &afterDecimal );
    00160                 decimal *= fast_atof_table[afterDecimal - in];
    00161
    00162                 value += decimal;
    00163
    00164                 in = afterDecimal;
    00165         }
    00166
    00167         if ('e' == *in || 'E' == *in)
    00168         {
    00169                 ++in;
    00170                 // Assume that the exponent is a whole number.
    00171                 // strtol10() will deal with both + and - signs,
    00172                 // but cast to (f32) to prevent overflow at FLT_MAX
    00173                 value *= (f32)pow(10.0f, (f32)strtol10(in, &in));
    00174         }
    00175
    00176         if(negative)
    00177                 out = -value;
    00178         else
    00179                 out = value;
    00180
    00181         return in;
    00182 }
    00183
    00186 inline float fast_atof(const char* floatAsString)
    00187 {
    00188         float ret;
    00189         fast_atof_move(floatAsString, ret);
    00190         return ret;
    00191 }
    00192
    00193 } // end namespace core
    00194 } // end namespace irr
    00195
    00196 #endif
    00197

| The Irrlicht Engine Documentation © 2003-2010 by Nikolaus Gebhardt. Generated on Sun Oct 24 12:41:56 2010 by Doxygen (1.6.2)