mirror of
https://github.com/thunderbrewhq/squall.git
synced 2025-12-12 10:32:29 +00:00
feat(string): add SStrToFloat
This commit is contained in:
parent
3d59699e1b
commit
28d60b4c4a
3 changed files with 203 additions and 0 deletions
139
storm/String.cpp
139
storm/String.cpp
|
|
@ -3,6 +3,7 @@
|
|||
#include "storm/Memory.hpp"
|
||||
#include "storm/string/bjhash.hpp"
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <strings.h>
|
||||
|
||||
|
|
@ -36,6 +37,10 @@ uint32_t offsetsFromUTF8[8] = {
|
|||
0
|
||||
};
|
||||
|
||||
int32_t s_initialized;
|
||||
|
||||
double s_realDigit[20][10];
|
||||
|
||||
void GetNextTextUpper(uint32_t* orig, const char** string, uint32_t* upper) {
|
||||
uint8_t byte = **string;
|
||||
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) {
|
||||
STORM_ASSERT(string);
|
||||
|
||||
|
|
@ -289,6 +331,103 @@ const char* SStrStr(const char* string, const char* search) {
|
|||
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) {
|
||||
STORM_ASSERT(string);
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ void SStrLower(char* string);
|
|||
|
||||
const char* SStrStr(const char* string, const char* search);
|
||||
|
||||
float SStrToFloat(const char* string);
|
||||
|
||||
int32_t SStrToInt(const char* string);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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]") {
|
||||
SECTION("converts empty string to int") {
|
||||
auto string = "";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue