mirror of
https://github.com/thunderbrewhq/squall.git
synced 2025-12-12 02:22:30 +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/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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 = "";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue