Перевод строки в дробное число без использования готовых методов и приведений типа
Вопрос: На вход даётся набор символов, соответствующий дробному числу. Как можно перевести эту строку в число, без использований приведений типа и готовых методов библиотек.
Я пытался реализовать подобный алгоритм, но к сожалению он работает исключительно с целыми числами:
#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;
}