double stod(const string &strInput)
{
    /* STOD: String to double  */
    /* Written by Mathias Van Malderen */
    /* It's not allowed to sell this source code ! */

    double dbl_one = 0;
    double dbl_two = 0;
    double dbl_final = 0;
    int strlen;
    bool dec_pt = false;
    int nums_before_dec = 0;
    int nums_after_dec = 0;

    strlen = strInput.length();

    /* Check whether the string can be transformed into a number */
    if(strInput[0] == '0' && strInput[1] == '0')
    {
        // invalid number !
        return 0;
    }
	
    for(int i = 0; i < strlen; i++)
    {
	if (strInput.c_str()[i] >= '0' && strInput.c_str()[i] <= '9')
	{
		// valid number !
	} else if(strInput[i] == '.') {
		if(dec_pt)
		{	
			// there was already a decimal point counted
			// invalid number !
			return 0;
		} else {
			dec_pt = true; // increment by one
		}
	} else {
		// invalid number !
		return 0;
	}
    }

    /* Convert the number */

    // STEP 1: Calculate the amount of numbers before/after the decimal point (if there's one)
    if(dec_pt) // if there's a decimal point in the number
    {
        for(int i = 0; i < strlen; i++)
        {
            if(strInput[i+1] != '.')
            {
                nums_before_dec++;
            } else {
                nums_before_dec++;
                break;
            }
        }
	nums_after_dec = strlen-nums_before_dec;
	nums_after_dec -= 1;
    } else {
	nums_after_dec = 0;
	nums_before_dec = strlen;
    }

    // STEP 2: Convert the string to a real number
    for(int i = 0; i < nums_before_dec; i++)
    {
        dbl_one += (strInput[i] - '0') * apow(10, (nums_before_dec - i));
    }

    dbl_one = dbl_one / 10; // little fix

    for(int i = 0; i < nums_after_dec; i++)
    {
        dbl_two += (strInput[i] - '0') / apow(10, i+1);
    }

    // STEP 3: Return the converted string as a double:
    dbl_final = dbl_one + dbl_two;
    return dbl_final;
}

/* This function 'apow' raises x to the power of y, it's a dependency of 'stod' */
double apow(const float &x, int y)
{
    double result = 1;
    if(y == 0)
        return result;

    if(y < 0)
    {
        y = -y;
        for(int i = 0; i < y; i++)
            result = result * x;
        return 1/result;
    }

    for(int i = 0; i < y; i++)
        result = result * x;

    return result;
}
2
Contributors
2
Replies
4
Views
7 Years
Discussion Span
Last Post by mvmalderen
0

Here's a better implementation of apow, assuming I don't have bugs.

double apow(double x, int y)
{
    if (y < 0)
        return apow(1 / x, -y);
    double m = x, p = 1.0;
    while (y) {
        if (y & 1)
            p = p * m;
        m = m * m;
        y = y >> 1;
    }
    return p;
}
0

I've rewritten my 'apow'-function, this is the final code:

double apow(const double &x, int y)
{
    double result = 1;
    if(y < 0)
	return apow(1/x, -y);
    for(int i = y; i > 0; i--)
	result *= x;
    return result;
}
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.