fast_atof.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  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. #ifndef IRR_FAST_ATOF_H_INCLUDED
  5. #define IRR_FAST_ATOF_H_INCLUDED
  6. #include "irrMath.h"
  7. #include "irrString.h"
  8. namespace irr
  9. {
  10. namespace core
  11. {
  12. //! Selection of characters which count as decimal point in fast_atof
  13. //! By default Irrlicht considers "." as the decimal point in numbers.
  14. //! But sometimes you might run into situations where floats were written in
  15. //! a local format with another decimal point like ",".
  16. //! Best solution is usually to fix those cases by converting the input.
  17. //! But if you don't have that choice you can set this to ".,".
  18. //! WARNING: This is not thread-safe, so don't change while there's a chance
  19. //! of another thread using fast_atof functions at the same time.
  20. // TODO: This should probably also be used in irr::core::string, but
  21. // the float-to-string code used there has to be rewritten first.
  22. IRRLICHT_API extern irr::core::stringc LOCALE_DECIMAL_POINTS;
  23. #define IRR_ATOF_TABLE_SIZE 17
  24. // we write [IRR_ATOF_TABLE_SIZE] here instead of [] to work around a swig bug
  25. const float fast_atof_table[17] = {
  26. 0.f,
  27. 0.1f,
  28. 0.01f,
  29. 0.001f,
  30. 0.0001f,
  31. 0.00001f,
  32. 0.000001f,
  33. 0.0000001f,
  34. 0.00000001f,
  35. 0.000000001f,
  36. 0.0000000001f,
  37. 0.00000000001f,
  38. 0.000000000001f,
  39. 0.0000000000001f,
  40. 0.00000000000001f,
  41. 0.000000000000001f,
  42. 0.0000000000000001f
  43. };
  44. //! Convert a simple string of base 10 digits into an unsigned 32 bit integer.
  45. /** \param[in] in: The string of digits to convert. No leading chars are
  46. allowed, only digits 0 to 9. Parsing stops at the first non-digit.
  47. \param[out] out: (optional) If provided, it will be set to point at the
  48. first character not used in the calculation.
  49. \return The unsigned integer value of the digits. If the string specifies
  50. too many digits to encode in an u32 then INT_MAX will be returned.
  51. */
  52. inline u32 strtoul10(const char* in, const char** out=0)
  53. {
  54. if (!in)
  55. {
  56. if (out)
  57. *out = in;
  58. return 0;
  59. }
  60. bool overflow=false;
  61. u32 unsignedValue = 0;
  62. while ( ( *in >= '0') && ( *in <= '9' ))
  63. {
  64. const u32 tmp = ( unsignedValue * 10 ) + ( *in - '0' );
  65. if (tmp<unsignedValue)
  66. {
  67. unsignedValue=(u32)0xffffffff;
  68. overflow=true;
  69. }
  70. if (!overflow)
  71. unsignedValue = tmp;
  72. ++in;
  73. }
  74. if (out)
  75. *out = in;
  76. return unsignedValue;
  77. }
  78. //! Convert a simple string of base 10 digits into a signed 32 bit integer.
  79. /** \param[in] in: The string of digits to convert. Only a leading - or +
  80. followed by digits 0 to 9 will be considered. Parsing stops at the first
  81. non-digit.
  82. \param[out] out: (optional) If provided, it will be set to point at the
  83. first character not used in the calculation.
  84. \return The signed integer value of the digits. If the string specifies
  85. too many digits to encode in an s32 then +INT_MAX or -INT_MAX will be
  86. returned.
  87. */
  88. inline s32 strtol10(const char* in, const char** out=0)
  89. {
  90. if (!in)
  91. {
  92. if (out)
  93. *out = in;
  94. return 0;
  95. }
  96. const bool negative = ('-' == *in);
  97. if (negative || ('+' == *in))
  98. ++in;
  99. const u32 unsignedValue = strtoul10(in,out);
  100. if (unsignedValue > (u32)INT_MAX)
  101. {
  102. if (negative)
  103. return (s32)INT_MIN;
  104. else
  105. return (s32)INT_MAX;
  106. }
  107. else
  108. {
  109. if (negative)
  110. return -((s32)unsignedValue);
  111. else
  112. return (s32)unsignedValue;
  113. }
  114. }
  115. //! Convert a hex-encoded character to an unsigned integer.
  116. /** \param[in] in The digit to convert. Only digits 0 to 9 and chars A-F,a-f
  117. will be considered.
  118. \return The unsigned integer value of the digit. 0xffffffff if the input is
  119. not hex
  120. */
  121. inline u32 ctoul16(char in)
  122. {
  123. if (in >= '0' && in <= '9')
  124. return in - '0';
  125. else if (in >= 'a' && in <= 'f')
  126. return 10u + in - 'a';
  127. else if (in >= 'A' && in <= 'F')
  128. return 10u + in - 'A';
  129. else
  130. return 0xffffffff;
  131. }
  132. //! Convert a simple string of base 16 digits into an unsigned 32 bit integer.
  133. /** \param[in] in: The string of digits to convert. No leading chars are
  134. allowed, only digits 0 to 9 and chars A-F,a-f are allowed. Parsing stops
  135. at the first illegal char.
  136. \param[out] out: (optional) If provided, it will be set to point at the
  137. first character not used in the calculation.
  138. \return The unsigned integer value of the digits. If the string specifies
  139. too many digits to encode in an u32 then INT_MAX will be returned.
  140. */
  141. inline u32 strtoul16(const char* in, const char** out=0)
  142. {
  143. if (!in)
  144. {
  145. if (out)
  146. *out = in;
  147. return 0;
  148. }
  149. bool overflow=false;
  150. u32 unsignedValue = 0;
  151. while (true)
  152. {
  153. u32 tmp = 0;
  154. if ((*in >= '0') && (*in <= '9'))
  155. tmp = (unsignedValue << 4u) + (*in - '0');
  156. else if ((*in >= 'A') && (*in <= 'F'))
  157. tmp = (unsignedValue << 4u) + (*in - 'A') + 10;
  158. else if ((*in >= 'a') && (*in <= 'f'))
  159. tmp = (unsignedValue << 4u) + (*in - 'a') + 10;
  160. else
  161. break;
  162. if (tmp<unsignedValue)
  163. {
  164. unsignedValue=(u32)INT_MAX;
  165. overflow=true;
  166. }
  167. if (!overflow)
  168. unsignedValue = tmp;
  169. ++in;
  170. }
  171. if (out)
  172. *out = in;
  173. return unsignedValue;
  174. }
  175. //! Convert a simple string of base 8 digits into an unsigned 32 bit integer.
  176. /** \param[in] in The string of digits to convert. No leading chars are
  177. allowed, only digits 0 to 7 are allowed. Parsing stops at the first illegal
  178. char.
  179. \param[out] out (optional) If provided, it will be set to point at the
  180. first character not used in the calculation.
  181. \return The unsigned integer value of the digits. If the string specifies
  182. too many digits to encode in an u32 then INT_MAX will be returned.
  183. */
  184. inline u32 strtoul8(const char* in, const char** out=0)
  185. {
  186. if (!in)
  187. {
  188. if (out)
  189. *out = in;
  190. return 0;
  191. }
  192. bool overflow=false;
  193. u32 unsignedValue = 0;
  194. while (true)
  195. {
  196. u32 tmp = 0;
  197. if ((*in >= '0') && (*in <= '7'))
  198. tmp = (unsignedValue << 3u) + (*in - '0');
  199. else
  200. break;
  201. if (tmp<unsignedValue)
  202. {
  203. unsignedValue=(u32)INT_MAX;
  204. overflow=true;
  205. }
  206. if (!overflow)
  207. unsignedValue = tmp;
  208. ++in;
  209. }
  210. if (out)
  211. *out = in;
  212. return unsignedValue;
  213. }
  214. //! Convert a C-style prefixed string (hex, oct, integer) into an unsigned 32 bit integer.
  215. /** \param[in] in The string of digits to convert. If string starts with 0x the
  216. hex parser is used, if only leading 0 is used, oct parser is used. In all
  217. other cases, the usual unsigned parser is used.
  218. \param[out] out (optional) If provided, it will be set to point at the
  219. first character not used in the calculation.
  220. \return The unsigned integer value of the digits. If the string specifies
  221. too many digits to encode in an u32 then INT_MAX will be returned.
  222. */
  223. inline u32 strtoul_prefix(const char* in, const char** out=0)
  224. {
  225. if (!in)
  226. {
  227. if (out)
  228. *out = in;
  229. return 0;
  230. }
  231. if ('0'==in[0])
  232. return ('x'==in[1] ? strtoul16(in+2,out) : strtoul8(in+1,out));
  233. return strtoul10(in,out);
  234. }
  235. //! Converts a sequence of digits into a whole positive floating point value.
  236. /** Only digits 0 to 9 are parsed. Parsing stops at any other character,
  237. including sign characters or a decimal point.
  238. \param in: the sequence of digits to convert.
  239. \param out: (optional) will be set to point at the first non-converted
  240. character.
  241. \return The whole positive floating point representation of the digit
  242. sequence.
  243. */
  244. inline f32 strtof10(const char* in, const char** out = 0)
  245. {
  246. if (!in)
  247. {
  248. if (out)
  249. *out = in;
  250. return 0.f;
  251. }
  252. const u32 MAX_SAFE_U32_VALUE = UINT_MAX / 10 - 10;
  253. u32 intValue = 0;
  254. // Use integer arithmetic for as long as possible, for speed
  255. // and precision.
  256. while ( ( *in >= '0') && ( *in <= '9' ) )
  257. {
  258. // If it looks like we're going to overflow, bail out
  259. // now and start using floating point.
  260. if (intValue >= MAX_SAFE_U32_VALUE)
  261. break;
  262. intValue = (intValue * 10) + (*in - '0');
  263. ++in;
  264. }
  265. f32 floatValue = (f32)intValue;
  266. // If there are any digits left to parse, then we need to use
  267. // floating point arithmetic from here.
  268. while ( ( *in >= '0') && ( *in <= '9' ) )
  269. {
  270. floatValue = (floatValue * 10.f) + (f32)(*in - '0');
  271. ++in;
  272. if (floatValue > FLT_MAX) // Just give up.
  273. break;
  274. }
  275. if (out)
  276. *out = in;
  277. return floatValue;
  278. }
  279. //! Provides a fast function for converting a string into a float.
  280. /** This is not guaranteed to be as accurate as atof(), but is
  281. approximately 6 to 8 times as fast.
  282. \param[in] in The string to convert.
  283. \param[out] result The resultant float will be written here.
  284. \return Pointer to the first character in the string that wasn't used
  285. to create the float value.
  286. */
  287. inline const char* fast_atof_move(const char* in, f32& result)
  288. {
  289. // Please run the regression test when making any modifications to this function.
  290. result = 0.f;
  291. if (!in)
  292. return 0;
  293. const bool negative = ('-' == *in);
  294. if (negative || ('+'==*in))
  295. ++in;
  296. f32 value = strtof10(in, &in);
  297. if ( LOCALE_DECIMAL_POINTS.findFirst(*in) >= 0 )
  298. {
  299. const char* afterDecimal = ++in;
  300. const f32 decimal = strtof10(in, &afterDecimal);
  301. const size_t numDecimals = afterDecimal - in;
  302. if (numDecimals < IRR_ATOF_TABLE_SIZE)
  303. {
  304. value += decimal * fast_atof_table[numDecimals];
  305. }
  306. else
  307. {
  308. value += decimal * (f32)pow(10.f, -(float)numDecimals);
  309. }
  310. in = afterDecimal;
  311. }
  312. if ('e' == *in || 'E' == *in)
  313. {
  314. ++in;
  315. // Assume that the exponent is a whole number.
  316. // strtol10() will deal with both + and - signs,
  317. // but calculate as f32 to prevent overflow at FLT_MAX
  318. // Using pow with float cast instead of powf as otherwise accuracy decreases.
  319. value *= (f32)pow(10.f, (f32)strtol10(in, &in));
  320. }
  321. result = negative?-value:value;
  322. return in;
  323. }
  324. //! Convert a string to a floating point number
  325. /** \param floatAsString The string to convert.
  326. \param out Optional pointer to the first character in the string that
  327. wasn't used to create the float value.
  328. \result Float value parsed from the input string
  329. */
  330. inline float fast_atof(const char* floatAsString, const char** out=0)
  331. {
  332. float ret;
  333. if (out)
  334. *out=fast_atof_move(floatAsString, ret);
  335. else
  336. fast_atof_move(floatAsString, ret);
  337. return ret;
  338. }
  339. } // end namespace core
  340. } // end namespace irr
  341. #endif