Преглед на файлове

LibC: Implement strtod()

Valtteri Koskivuori преди 5 години
родител
ревизия
fe1df9e9fb
променени са 1 файла, в които са добавени 68 реда и са изтрити 4 реда
  1. 68 4
      Libraries/LibC/stdlib.cpp

+ 68 - 4
Libraries/LibC/stdlib.cpp

@@ -256,10 +256,74 @@ int putenv(char* new_var)
 
 double strtod(const char* str, char** endptr)
 {
-    (void)str;
-    (void)endptr;
-    dbgprintf("LibC: strtod: '%s'\n", str);
-    ASSERT_NOT_REACHED();
+    size_t len = strlen(str);
+    size_t weight = 1;
+    int exp_val = 0;
+    double value = 0.0f;
+    double fraction = 0.0f;
+    bool has_sign = false;
+    bool is_negative = false;
+    bool is_fractional = false;
+    bool is_scientific = false;
+
+    if (str[0] == '-') {
+        is_negative = true;
+        has_sign = true;
+    }
+    if (str[0] == '+') {
+        has_sign = true;
+    }
+    size_t i;
+    for (i = has_sign; i < len; i++) {
+
+        // Looks like we're about to start working on the fractional part
+        if (str[i] == '.') {
+            is_fractional = true;
+            continue;
+        }
+
+        if (str[i] == 'e' || str[i] == 'E') {
+            if (str[i + 1] == '-' || str[i + 1] == '+')
+                exp_val = atoi(str + i + 2);
+            else
+                exp_val = atoi(str + i + 1);
+
+            is_scientific = true;
+            continue;
+        }
+
+        if (str[i] < '0' || str[i] > '9' || exp_val != 0)
+            continue;
+
+        if (is_fractional) {
+            fraction *= 10;
+            fraction += str[i] - '0';
+            weight *= 10;
+        } else {
+            value = value * 10;
+            value += str[i] - '0';
+        }
+    }
+
+    fraction /= weight;
+    value += fraction;
+
+    if (is_scientific) {
+        bool divide = exp_val < 0;
+        if (divide)
+            exp_val *= -1;
+
+        for (int i = 0; i < exp_val; i++) {
+            if (divide)
+                value /= 10;
+            else
+                value *= 10;
+        }
+    }
+    //FIXME: Not entirely sure if this is correct, but seems to work.
+    if (endptr)
+        *endptr = const_cast<char*>(str + i);
+    return is_negative ? -value : value;
 }
 
 long double strtold(const char* str, char** endptr)