feat(string): add SStrToFloat

This commit is contained in:
fallenoak 2020-11-21 14:05:13 -06:00
parent 3d59699e1b
commit 28d60b4c4a
No known key found for this signature in database
GPG key ID: 7628F8E61AEA070D
3 changed files with 203 additions and 0 deletions

View file

@ -3,6 +3,7 @@
#include "storm/Memory.hpp" #include "storm/Memory.hpp"
#include "storm/string/bjhash.hpp" #include "storm/string/bjhash.hpp"
#include <cctype> #include <cctype>
#include <cmath>
#include <cstring> #include <cstring>
#include <strings.h> #include <strings.h>
@ -36,6 +37,10 @@ uint32_t offsetsFromUTF8[8] = {
0 0
}; };
int32_t s_initialized;
double s_realDigit[20][10];
void GetNextTextUpper(uint32_t* orig, const char** string, uint32_t* upper) { void GetNextTextUpper(uint32_t* orig, const char** string, uint32_t* upper) {
uint8_t byte = **string; uint8_t byte = **string;
int32_t v3 = bytesFromUTF8[byte]; int32_t v3 = bytesFromUTF8[byte];
@ -132,6 +137,43 @@ void GetNextTextUpper(uint32_t* orig, const char** string, uint32_t* upper) {
} }
} }
void InitializeFloatDigits() {
for (int32_t i = -1; i > -21; i--) {
for (int32_t j = 0; j < 10; j++) {
double v3 = 10.0;
int32_t v4 = i < 0 ? -i : i;
double v5 = 1.0;
while (true) {
if (v4 & 1) {
v5 *= v3;
}
v4 >>= 1;
if (!v4) {
break;
}
v3 *= v3;
}
double v6 = i < 0 ? 1.0 / v5 : v5;
double v7 = v6 * static_cast<double>(j);
s_realDigit[-i - 1][j] = v7;
}
}
}
void SStrInitialize() {
if (!s_initialized) {
InitializeFloatDigits();
s_initialized = 1;
}
}
const char* SStrChr(const char* string, char search) { const char* SStrChr(const char* string, char search) {
STORM_ASSERT(string); STORM_ASSERT(string);
@ -289,6 +331,103 @@ const char* SStrStr(const char* string, const char* search) {
return substring; return substring;
} }
float SStrToFloat(const char* string) {
STORM_ASSERT(string);
SStrInitialize();
double result;
bool negative;
if (*string == '-') {
negative = true;
string++;
}
double v16 = 10.0;
double v4 = 0.0;
uint32_t v5 = *string - '0';
const char* v6 = string;
if (v5 >= 10) {
v5 = 0;
result = static_cast<double>(v5);
} else {
string++;
uint32_t v8 = *string - '0';
if (v8 >= 10) {
result = static_cast<double>(v5);
} else {
do {
v5 = v8 + 10 * v5;
string++;
if (v5 >= 0x19999999) {
v4 = v4 * pow(10.0, string - v6) + static_cast<double>(v5);
v5 = 0;
v6 = string;
}
v8 = *string - '0';
} while (v8 < 10);
if (v4 == 0.0) {
result = static_cast<double>(v5);
} else {
result = pow(10.0, string - v6) * v4 + static_cast<double>(v5);
}
}
}
if (*string == '.') {
string++;
uint32_t v23 = *string - '0';
int32_t v24 = 0;
if (v23 < 10) {
int32_t v25 = 0;
int32_t v26 = -1;
double v31;
do {
string++;
if (v24 < 20) {
v31 = s_realDigit[0][v25 + v23];
} else {
v31 = pow(v16, v26) * v23;
}
result += v31;
v23 = *string - '0';
v24++;
v26--;
v25 += 10;
} while (v23 < 10);
}
}
if (*string == 'e' || *string == 'E') {
const char* v32 = string + 1;
if (*v32 == '+') {
v32++;
}
result *= pow(10.0, SStrToInt(v32));
}
if (negative) {
result = -result;
}
return static_cast<float>(result);
}
int32_t SStrToInt(const char* string) { int32_t SStrToInt(const char* string) {
STORM_ASSERT(string); STORM_ASSERT(string);

View file

@ -27,6 +27,8 @@ void SStrLower(char* string);
const char* SStrStr(const char* string, const char* search); const char* SStrStr(const char* string, const char* search);
float SStrToFloat(const char* string);
int32_t SStrToInt(const char* string); int32_t SStrToInt(const char* string);
#endif #endif

View file

@ -218,6 +218,68 @@ TEST_CASE("SStrStr", "[string]") {
} }
} }
TEST_CASE("SStrToFloat", "[string]") {
SECTION("converts empty string to float") {
auto string = "";
auto result = SStrToFloat(string);
REQUIRE(result == 0.0f);
}
SECTION("converts whitespace string to float") {
auto string = " ";
auto result = SStrToFloat(string);
REQUIRE(result == 0.0f);
}
SECTION("converts string with positive int to float") {
auto string = "123";
auto result = SStrToFloat(string);
REQUIRE(result == 123.0f);
}
SECTION("converts string with negative int to float") {
auto string = "-123";
auto result = SStrToFloat(string);
REQUIRE(result == -123.0f);
}
SECTION("converts string with positive float to float") {
auto string = "1.5";
auto result = SStrToFloat(string);
REQUIRE(result == 1.5f);
}
SECTION("converts string with negative float to float") {
auto string = "-1.5";
auto result = SStrToFloat(string);
REQUIRE(result == -1.5f);
}
SECTION("converts string with float and positive exponent to float") {
auto string = "1.5e3";
auto result = SStrToFloat(string);
REQUIRE(result == 1500.0f);
}
SECTION("converts string with float and negative exponent to float") {
auto string = "1500.0e-3";
auto result = SStrToFloat(string);
REQUIRE(result == 1.5f);
}
SECTION("converts string with zero to float") {
auto string = "0";
auto result = SStrToFloat(string);
REQUIRE(result == 0.0f);
}
SECTION("converts string with leading zero to float") {
auto string = "01";
auto result = SStrToFloat(string);
REQUIRE(result == 1.0f);
}
}
TEST_CASE("SStrToInt", "[string]") { TEST_CASE("SStrToInt", "[string]") {
SECTION("converts empty string to int") { SECTION("converts empty string to int") {
auto string = ""; auto string = "";