#include /*static int _strlen(char s[]) { int i; for (i=0; s[i] != '\0'; i++) {} return i; }*/ /*static int _isspace(char s) { return s == ' ' || s == '\t'; }*/ static int _isdigit(char s) { return '0' <= s && s <= '9'; } static int _abs(int a) { if (a >=0) { return a; } else { return -1 * a; } } static int _intval(char s) { return s - '0'; } static int _isupper(char s) { return 'A' <= s && s <= 'Z'; } static char _tolower(char s) { static int diff = 'A' - 'a'; if (_isupper(s)) { return s - diff; } else { return s; } } static int _atoi_internal(char s[], int n) { if (s == NULL || *s == '\0' || !_isdigit(*s)) { return n; } __attribute__((musttail)) // Functional programinng enabler :) return _atoi_internal(s + 1, (10 * n) + _intval(*s)); } /** * Converts a string to an integer * string must be null terminated * overflow isn't detected, int is the limit */ int _atoi(char s[]) { int i = 0; int sign = (s[i] == '-') ? -1 : 1; if (s[i] == '+' || s[i] == '-') i++; return _atoi_internal(s + i, 0) * sign; } /** * Converts a string to a double * * string must be null terminated. * overflow isn't detected, and double precision is the limit. */ double _atof(char s[]) { double val, power, ee; int i = 0; int sign = (s[i] == '-') ? -1 : 1; if (s[i] == '+' || s[i] == '-') i++; for (val = 0.0; _isdigit(s[i]); i++) val = 10.0 * val + _intval(s[i]); if (s[i] == '.') i++; for (power = 1.0; _isdigit(s[i]); i++) { val = 10.0 * val + _intval(s[i]); power *= 10.0; } ee = 1.0; if (_tolower(s[i]) == 'e') { i++; int exponent = _atoi(s + i); if (exponent >= 0) { for (int j=0;j<_abs(exponent);j++) ee *= 10.0; } else { for (int j=0;j<_abs(exponent);j++) ee /= 10.0; } } return (sign * val / power) * ee; } void testb(char s[]) { printf("atoi s = [%s] result = [%d]\n", s, _atoi(s)); } void test(char s[]) { printf("atof s = [%s] result = [%lf]\n", s, _atof(s)); } int main(void) { test(""); test("gibber"); test("\0"); test("1"); test("1.0"); test("99.0"); test("-10.0"); test("+11.0"); test("++11.0"); test("-11111111111111111111111111111111111111111111111111111111111111111111111111111111111.1"); testb("gibber"); testb(""); testb("\0"); testb("1"); testb("1.5"); testb("+2.6"); testb("-7.8"); testb("--7.8"); test("+11.0e5"); test("2.75345e3"); test("2.75345e-3"); test("2.75345E-3"); }