[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tyndur-devel] [PATCH 1/4] libc: strtod



+ libc: Eine halbe Implementierung von strtod

Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
 src/include/stdlib.h |    4 +++
 src/lib/string.c     |   70 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+), 0 deletions(-)

diff --git a/src/include/stdlib.h b/src/include/stdlib.h
index d56d879..873dda8 100644
--- a/src/include/stdlib.h
+++ b/src/include/stdlib.h
@@ -58,6 +58,10 @@ long strtol(const char* str, char** endptr, int base);
 unsigned long strtoul(const char *nptr, char **endptr, int base);
 unsigned long long strtoull(const char *nptr, char **endptr, int base);
 
+long double strtold(const char* nptr, char** end);
+double strtod(const char* nptr, char** end);
+float strtof(const char* nptr, char** end);
+
 int atoi(const char* s);
 long atol(const char* str);
 
diff --git a/src/lib/string.c b/src/lib/string.c
index f6f4132..d6d662f 100644
--- a/src/lib/string.c
+++ b/src/lib/string.c
@@ -198,6 +198,76 @@ long atol(const char *str)
     return result;
 }
 
+long double strtold(const char* nptr, char** end)
+{
+    long double result = 0;
+    long double frac = 0;
+    long double base = 10.0;
+    int neg = 0;
+    int decimal = 0;
+
+    // Leerzeichen am Anfang muessen ignoriert werden
+    while (isspace(*nptr)) {
+        nptr++;
+    }
+
+    // Vorzeichen
+    if (*nptr == '+') {
+        nptr++;
+    } else if (*nptr == '-') {
+        neg = 1;
+        nptr++;
+    }
+
+    // Ergebnis berechnen
+    result = 0;
+    while (*nptr) {
+        switch (*nptr) {
+            case '0' ... '9':
+                if (*nptr - '0' > base - 1) {
+                    goto out;
+                }
+                if (!decimal) {
+                    result = result * base + (*nptr - '0');
+                } else {
+                    frac = frac + ((*nptr - '0') / base);
+                    base *= 10.0;
+                }
+                break;
+
+            case '.':
+                decimal = 1;
+                break;
+
+            case 'E':
+            case 'e':
+                // TODO
+
+            default:
+                goto out;
+        }
+        nptr++;
+    }
+out:
+    result += frac;
+
+    if (end != NULL) {
+        *end = (char*) nptr;
+    }
+
+    return neg ? - result : result;
+}
+
+double strtod(const char* nptr, char** end)
+{
+    return strtold(nptr, end);
+}
+
+float strtof(const char* nptr, char** end)
+{
+    return strtold(nptr, end);
+}
+
 /**
  * Zwei Strings unter Beruecksichtigung des aktuellen locales vergleichen
  */
-- 
1.6.0.2