typename std::enable_if<std::is_floating_point<T>::value, bool>::type toType(T& r, const char* p) { // Skip leading white space, if any. while (white_space(*p)) { p += 1; } r = 0.0; int c = 0; // counter to check how many numbers we got! // Get the sign! bool neg = false; if (*p == '-') { neg = true; ++p; } else if (*p == '+') { neg = false; ++p; } // Get the digits before decimal point while (valid_digit(*p)) { r = (r * 10.0) + (*p - '0'); ++p; ++c; } // Get the digits after decimal point if (*p == '.') { T f = 0.0; T scale = 1.0; ++p; while (*p >= '0' && *p <= '9') { f = (f * 10.0) + (*p - '0'); ++p; scale *= 10.0; ++c; } r += f / scale; } // FIRST CHECK: if (c == 0) { return false; } // we got no dezimal places: invalid number! // Get the digits after the "e"/"E" (exponenet) if (*p == 'e' || *p == 'E') { unsigned int e = 0; bool negE = false; ++p; if (*p == '-') { negE = true; ++p; } else if (*p == '+') { negE = false; ++p; } // Get exponent c = 0; while (valid_digit(*p)) { e = (e * 10) + (*p - '0'); ++p; ++c; } // Check exponent limits! // if( !neg && e>std::numeric_limits<T>::max_exponent10 ){ // e = std::numeric_limits<T>::max_exponent10; // }else if(e < std::numeric_limits<T>::min_exponent10 ){ // e = std::numeric_limits<T>::max_exponent10; // } // SECOND CHECK: if (c == 0) { return false; } // we got no exponent: invalid number! T scaleE = 1.0; // Calculate scaling factor. while (e >= 50) { scaleE *= 1E50; e -= 50; } // while (e >= 8) { scaleE *= 1E8; e -= 8; } while (e > 0) { scaleE *= 10.0; e -= 1; } if (negE) { r /= scaleE; } else { r *= scaleE; } } // POST CHECK: // skip post whitespaces while (white_space(*p)) { ++p; } if (*p != '\0') { return false; } // if next character is not the terminating character: invalid number! // Apply sign to number if (neg) { r = -r; } return true; }
static float _atof(const char *p) { int frac = 0; float sign, value, scale; // Skip leading white space, if any. while (white_space(*p) ) { p += 1; } // Get sign, if any. sign = 1.0f; if (*p == '-') { sign = -1.0f; p += 1; } else if (*p == '+') { p += 1; } // Get digits before decimal point or exponent, if any. value = 0.0f; while (valid_digit(*p)) { value = value * 10.0f + (*p - '0'); p += 1; } // Get digits after decimal point, if any. if (*p == '.') { float pow10 = 10.0f; p += 1; while (valid_digit(*p)) { value += (*p - '0') / pow10; pow10 *= 10.0f; p += 1; } } // Handle exponent, if any. scale = 1.0f; if ((*p == 'e') || (*p == 'E')) { unsigned int expon; p += 1; // Get sign of exponent, if any. frac = 0; if (*p == '-') { frac = 1; p += 1; } else if (*p == '+') { p += 1; } // Get digits of exponent, if any. expon = 0; while (valid_digit(*p)) { expon = expon * 10 + (*p - '0'); p += 1; } if (expon > 308) expon = 308; // Calculate scaling factor. // while (expon >= 50) { scale *= 1E50f; expon -= 50; } while (expon >= 8) { scale *= 1E8f; expon -= 8; } while (expon > 0) { scale *= 10.0f; expon -= 1; } } // Return signed and scaled floating point result. return sign * (frac ? (value / scale) : (value * scale)); }
T CharToNum::atof2(const char *num) { //Improvement of the atof() function //Original source from http://tinodidriksen.com/2011/05/28/cpp-convert-string-to-double-speed/ // Tino Didriksen, 2014 // Skip leading white space, if any. while (white_space(*num)) { num += 1; } T r = 0.0; unsigned int c = 0; // counter to check how many numbers we got! // Get the sign! bool neg = false; if (*num == '-') { neg = true; ++num; } else if (*num == '+'){ neg = false; ++num; } // Get the digits before decimal point while (valid_digit(*num)) { r = (r * 10.0) + (*num - '0'); ++num; ++c; } // Get the digits after decimal point if (*num == '.') { T f = 0.0; T scale = 1.0; ++num; while (*num >= '0' && *num <= '9') { f = (f*10.0) + (*num - '0'); ++num; scale *= 10.0; ++c; } r += f / scale; } // FIRST CHECK: if (c == 0) { // We got no dezimal places! this cannot be any number! throw ("BadDataException: the strinh has no dezimal place.", "Conversion to number aborted."); } // Get the digits after the "e"/"E" (exponenet) if (*num == 'e' || *num == 'E'){ unsigned int e = 0; bool negE = false; ++num; if (*num == '-') { negE = true; ++num; } else if (*num == '+') { negE = false; ++num; } // Get exponent c = 0; while (valid_digit(*num)) { e = (e * 10) + (*num - '0'); ++num; ++c; } if (!neg && e > std::numeric_limits<T>::max_exponent10) { e = std::numeric_limits<T>::max_exponent10; } else if (e < std::numeric_limits<T>::min_exponent10) { e = std::numeric_limits<T>::max_exponent10; } // SECOND CHECK: if (c == 0) { // We got no exponent! this was not intended!! throw ("BadDataException: the string has no exponent.", "Conversion to number aborted."); } T scaleE = 1.0; // Calculate scaling factor. while (e >= 50) { scaleE *= 1E50; e -= 50; } while (e > 0) { scaleE *= 10.0; e -= 1; } if (negE) { r /= scaleE; } else { r *= scaleE; } } // POST CHECK: // skip post whitespaces while (white_space(*num)) { ++num; } if (*num != '\0') { // If next character is not the terminating character throw ("BadDataException: the next character is not \n.", "Conversion to number aborted."); } // Apply sign to number if (neg) { r = -r; } return r; }