diff --git a/Libraries/LibC/stdlib.cpp b/Libraries/LibC/stdlib.cpp index 4a5f23fe6c..8e9e65bc50 100644 --- a/Libraries/LibC/stdlib.cpp +++ b/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(str + i); + return is_negative ? -value : value; } long double strtold(const char* str, char** endptr)