Перевод строки в дробное число без использования готовых методов и приведений типа

Вопрос: На вход даётся набор символов, соответствующий дробному числу. Как можно перевести эту строку в число, без использований приведений типа и готовых методов библиотек.

Я пытался реализовать подобный алгоритм, но к сожалению он работает исключительно с целыми числами:

#include <iostream>
#include <string>
using namespace std;



int to_int(string &num, int &number){
    if (num[0] == '-') {
    for (int i = 1; i < num.size(); i++) {
        int digit = (int) num[i] - (int) '0';
        number = number * 10 + digit;
    }
    number = number * (-1);}

    else {
        for (int i = 0; i < num.size(); i++) {
            int digit = (int) num[i] - (int) '0';
            number = number * 10 + digit;
        }
    }
    return number;
}


int main() {
    string num;
    cin >> num;
    int number = 0;

    cout << to_int(num,number) << endl;
}

UPD: строка может быть дана с минусом.


Ответы (2 шт):

Автор решения: kroninberg

Как-то так:

#include <iostream>
#include <string>
using namespace std;


double to_int(const string &str, double &number){
    number = 0; // На всякий
    int i;
    bool is_neg = str[0] == '-';
    for (i = is_neg; i < str.size() && str[i] != '.'; ++i) {
        int digit = str[i] - '0';    // Нет нужды явно приводить к int
        number = number * 10 + digit;
    }
    double num = 0;    // Дробная часть
    for (int j = str.size() - 1; i < j ; --j) {
        int digit = str[j] - '0';
        num = num / 10 + digit;
    }
    number = (is_neg?-1.:1.) * (number + num / 10);
    return number;
}

int main() {
    string str;
    cin >> str;
    double number = 0;

    cout << to_int(str, number) << endl;
}
→ Ссылка
Автор решения: Harry

Все-таки немного времени в пятничный вечер без воздушных тревог :) есть... Набросал такой вот простенький автомат
введите сюда описание изображения
и его тривиальную реализацию...

class Double
{
public:
    Double(const char * s);

    operator double() const { return sign*v*pow(10,ex*exsn); }
private:

    int start(char c);
    int zero (char c);
    int one  (char c);
    int two  (char c);
    int three(char c);
    int four (char c);
    int five (char c);

    double v  =  0;
    int sign  =  1;
    int ex    =  0;
    int exsn  =  1;
    int state = -1;
    double p  = 10;
};

Double::Double(const char * s)
{
    if ((state = start(*s++)) < 0) return;
    for(;*s;++s)
    {
        switch(state)
        {
        case 0: state = zero (*s); break;
        case 1: state = one  (*s); break;
        case 2: state = two  (*s); break;
        case 3: state = three(*s); break;
        case 4: state = four (*s); break;
        case 5: state = five (*s); break;
        default: return;
        }
    }
}

int Double::start(char c)
{
    if (c == '-' || c == '+') { sign = (c == '-') ? -1 : 1; return 0; }
    if (c == '.') return 2;
    if (isdigit(c)) { v = v*10 + (c-'0'); return 1; }
    return -1;
}

int Double::zero(char c)
{
    if (c == '.') return 2;
    if (isdigit(c)) { v = v*10 + (c-'0'); return 1; }
    return -1;
}

int Double::one(char c)
{
    if (c == '.') return 2;
    if (c == 'e' || c == 'E') return 4;
    if (isdigit(c)) { v = v*10 + (c-'0'); return 1; }
    return -1;
}

int Double::two(char c)
{
    if (isdigit(c)) { v = v + (c-'0')/p; p*=10; return 3; }
    return -1;
}

int Double::three(char c)
{
    if (isdigit(c)) { v = v + (c-'0')/p; p*=10; return 3; }
    if (c == 'e' || c == 'E') return 4;
    return -1;
}

int Double::four(char c)
{
    if (c == '-' || c == '+') { exsn = (c == '-') ? -1 : 1; return 5; }
    if (isdigit(c)) { ex = ex*10 + (c-'0'); return 5; }
    return -1;
}

int Double::five(char c)
{
    if (isdigit(c)) { ex = ex*10 + (c-'0'); return 5; }
    return -1;
}
→ Ссылка