Для сравнения, вот простой, простой вариант atoi()
, который принимает произвольное основание использовать (т.е. не обязательно 10):
#include <ctype.h>
int myatoi(const char *str, int b)
{
const char *p;
int ret = 0;
for(p = str; *p != '\0' && isspace(*p); p++)
;
for(; *p != '\0' && isdigit(*p); p++)
ret = b * ret + (*p - '0');
return ret;
}
(. Обратите внимание, что я оставил негативную обработку номер)
После того, как вы получили, что это просто обнаружить десятичную точку и обрабатывать цифр справа от него, а также:
double myatof(const char *str, int b)
{
const char *p;
double ret = 0;
for(p = str; *p != '\0' && isspace(*p); p++)
;
for(; *p != '\0' && isdigit(*p); p++)
ret = b * ret + (*p - '0');
if(*p == '.')
{
double fac = b;
for(p++; *p != '\0' && isdigit(*p); p++)
{
ret += (*p - '0')/fac;
fac *= b;
}
}
return ret;
}
slightl у менее очевидный подход, который может быть численно лучше себя, это:
double myatof2(const char *str, int b)
{
const char *p;
long int n = 0;
double denom = 1;
for(p = str; *p != '\0' && isspace(*p); p++)
;
for(; *p != '\0' && isdigit(*p); p++)
n = b * n + (*p - '0');
if(*p == '.')
{
for(p++; *p != '\0' && isdigit(*p); p++)
{
n = b * n + (*p - '0');
denom *= b;
}
}
return n/denom;
}
Я проверил это с
#include <stdio.h>
int main()
{
printf("%d\n", myatoi("123", 10));
printf("%d\n", myatoi("10101", 2));
printf("%f\n", myatof("123.123", 10));
printf("%f\n", myatof("101.101", 2));
printf("%f\n", myatof2("123.123", 10));
printf("%f\n", myatof2("101.101", 2));
return 0;
}
, который печатает
123
21
123.123000
5.625000
123.123000
5.625000
, как и ожидалось. более
Одно примечание: эти функции не поддерживают основы больше, чем 10.
Можете ли вы показать пример значения с плавающей запятой для преобразования? –
Вы можете просто преобразовать деталь до и после '.' используя strtol, а затем делая float из обоих –
@ZachP. Это работает для чисел до десятичной точки, но как насчет чисел после? –