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;
}
Beispiel #2
0
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));
}
Beispiel #3
0
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;
}