123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- #pragma once
- #include "irrTypes.h"
- #include <cfloat>
- #include <climits>
- #include <cmath>
- namespace irr
- {
- namespace core
- {
- #define IRR_ATOF_TABLE_SIZE 17
- const float fast_atof_table[17] = {
- 0.f,
- 0.1f,
- 0.01f,
- 0.001f,
- 0.0001f,
- 0.00001f,
- 0.000001f,
- 0.0000001f,
- 0.00000001f,
- 0.000000001f,
- 0.0000000001f,
- 0.00000000001f,
- 0.000000000001f,
- 0.0000000000001f,
- 0.00000000000001f,
- 0.000000000000001f,
- 0.0000000000000001f};
- inline u32 strtoul10(const char *in, const char **out = 0)
- {
- if (!in) {
- if (out)
- *out = in;
- return 0;
- }
- bool overflow = false;
- u32 unsignedValue = 0;
- while ((*in >= '0') && (*in <= '9')) {
- const u32 tmp = (unsignedValue * 10) + (*in - '0');
- if (tmp < unsignedValue) {
- unsignedValue = (u32)0xffffffff;
- overflow = true;
- }
- if (!overflow)
- unsignedValue = tmp;
- ++in;
- }
- if (out)
- *out = in;
- return unsignedValue;
- }
- inline s32 strtol10(const char *in, const char **out = 0)
- {
- if (!in) {
- if (out)
- *out = in;
- return 0;
- }
- const bool negative = ('-' == *in);
- if (negative || ('+' == *in))
- ++in;
- const u32 unsignedValue = strtoul10(in, out);
- if (unsignedValue > (u32)INT_MAX) {
- if (negative)
- return (s32)INT_MIN;
- else
- return (s32)INT_MAX;
- } else {
- if (negative)
- return -((s32)unsignedValue);
- else
- return (s32)unsignedValue;
- }
- }
- inline u32 ctoul16(char in)
- {
- if (in >= '0' && in <= '9')
- return in - '0';
- else if (in >= 'a' && in <= 'f')
- return 10u + in - 'a';
- else if (in >= 'A' && in <= 'F')
- return 10u + in - 'A';
- else
- return 0xffffffff;
- }
- inline u32 strtoul16(const char *in, const char **out = 0)
- {
- if (!in) {
- if (out)
- *out = in;
- return 0;
- }
- bool overflow = false;
- u32 unsignedValue = 0;
- while (true) {
- u32 tmp = 0;
- if ((*in >= '0') && (*in <= '9'))
- tmp = (unsignedValue << 4u) + (*in - '0');
- else if ((*in >= 'A') && (*in <= 'F'))
- tmp = (unsignedValue << 4u) + (*in - 'A') + 10;
- else if ((*in >= 'a') && (*in <= 'f'))
- tmp = (unsignedValue << 4u) + (*in - 'a') + 10;
- else
- break;
- if (tmp < unsignedValue) {
- unsignedValue = (u32)INT_MAX;
- overflow = true;
- }
- if (!overflow)
- unsignedValue = tmp;
- ++in;
- }
- if (out)
- *out = in;
- return unsignedValue;
- }
- inline u32 strtoul8(const char *in, const char **out = 0)
- {
- if (!in) {
- if (out)
- *out = in;
- return 0;
- }
- bool overflow = false;
- u32 unsignedValue = 0;
- while (true) {
- u32 tmp = 0;
- if ((*in >= '0') && (*in <= '7'))
- tmp = (unsignedValue << 3u) + (*in - '0');
- else
- break;
- if (tmp < unsignedValue) {
- unsignedValue = (u32)INT_MAX;
- overflow = true;
- }
- if (!overflow)
- unsignedValue = tmp;
- ++in;
- }
- if (out)
- *out = in;
- return unsignedValue;
- }
- inline u32 strtoul_prefix(const char *in, const char **out = 0)
- {
- if (!in) {
- if (out)
- *out = in;
- return 0;
- }
- if ('0' == in[0])
- return ('x' == in[1] ? strtoul16(in + 2, out) : strtoul8(in + 1, out));
- return strtoul10(in, out);
- }
- inline f32 strtof10(const char *in, const char **out = 0)
- {
- if (!in) {
- if (out)
- *out = in;
- return 0.f;
- }
- const u32 MAX_SAFE_U32_VALUE = UINT_MAX / 10 - 10;
- u32 intValue = 0;
-
-
- while ((*in >= '0') && (*in <= '9')) {
-
-
- if (intValue >= MAX_SAFE_U32_VALUE)
- break;
- intValue = (intValue * 10) + (*in - '0');
- ++in;
- }
- f32 floatValue = (f32)intValue;
-
-
- while ((*in >= '0') && (*in <= '9')) {
- floatValue = (floatValue * 10.f) + (f32)(*in - '0');
- ++in;
- if (floatValue > FLT_MAX)
- break;
- }
- if (out)
- *out = in;
- return floatValue;
- }
- inline const char *fast_atof_move(const char *in, f32 &result)
- {
-
- result = 0.f;
- if (!in)
- return 0;
- const bool negative = ('-' == *in);
- if (negative || ('+' == *in))
- ++in;
- f32 value = strtof10(in, &in);
- if (*in == '.') {
- const char *afterDecimal = ++in;
- const f32 decimal = strtof10(in, &afterDecimal);
- const size_t numDecimals = afterDecimal - in;
- if (numDecimals < IRR_ATOF_TABLE_SIZE) {
- value += decimal * fast_atof_table[numDecimals];
- } else {
- value += decimal * std::pow(10.f, -(float)numDecimals);
- }
- in = afterDecimal;
- }
- if ('e' == *in || 'E' == *in) {
- ++in;
-
-
-
-
- value *= std::pow(10.f, (f32)strtol10(in, &in));
- }
- result = negative ? -value : value;
- return in;
- }
- inline float fast_atof(const char *floatAsString, const char **out = 0)
- {
- float ret;
- if (out)
- *out = fast_atof_move(floatAsString, ret);
- else
- fast_atof_move(floatAsString, ret);
- return ret;
- }
- }
- }
|