Add support for scientific notation in strtof32
This commit is contained in:
parent
44ef3759e5
commit
034de12235
79
dqn.h
79
dqn.h
@ -535,11 +535,14 @@ DQN_FILE_SCOPE inline bool operator==(DqnV3 a, DqnV3 b) { return DqnV3_E
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Vec4
|
// Vec4
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
typedef union DqnV4
|
typedef union DqnV4 {
|
||||||
{
|
|
||||||
struct { f32 x, y, z, w; };
|
struct { f32 x, y, z, w; };
|
||||||
|
DqnV3 xyz;
|
||||||
|
|
||||||
struct { f32 r, g, b, a; };
|
struct { f32 r, g, b, a; };
|
||||||
f32 e[4];
|
DqnV3 rgb;
|
||||||
|
|
||||||
|
f32 e[4];
|
||||||
DqnV2 v2[2];
|
DqnV2 v2[2];
|
||||||
} DqnV4;
|
} DqnV4;
|
||||||
|
|
||||||
@ -2643,11 +2646,18 @@ DQN_FILE_SCOPE f32 Dqn_StrToF32(const char *const buf, const i32 bufSize)
|
|||||||
|
|
||||||
i32 index = 0;
|
i32 index = 0;
|
||||||
bool isNegative = false;
|
bool isNegative = false;
|
||||||
if (buf[index++] == '-') isNegative = true;
|
if (buf[index] == '-')
|
||||||
|
{
|
||||||
|
index++;
|
||||||
|
isNegative = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool isPastDecimal = false;
|
bool isPastDecimal = false;
|
||||||
i32 numDigitsAfterDecimal = 0;
|
i32 numDigitsAfterDecimal = 0;
|
||||||
i32 rawNumber = 0;
|
i32 rawNumber = 0;
|
||||||
|
|
||||||
|
f32 digitShiftValue = 1.0f;
|
||||||
|
f32 digitShiftMultiplier = 0.1f;
|
||||||
for (i32 i = index; i < bufSize; i++)
|
for (i32 i = index; i < bufSize; i++)
|
||||||
{
|
{
|
||||||
char ch = buf[i];
|
char ch = buf[i];
|
||||||
@ -2656,26 +2666,61 @@ DQN_FILE_SCOPE f32 Dqn_StrToF32(const char *const buf, const i32 bufSize)
|
|||||||
isPastDecimal = true;
|
isPastDecimal = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (!DqnChar_IsDigit(ch))
|
// Handle scientific notation
|
||||||
|
else if (ch == 'e')
|
||||||
|
{
|
||||||
|
bool digitShiftIsPositive = true;
|
||||||
|
if (i < bufSize)
|
||||||
|
{
|
||||||
|
if (buf[i + 1] == '-') digitShiftIsPositive = false;
|
||||||
|
DQN_ASSERT(buf[i + 1] == '-' || buf[i + 1] == '+');
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
i32 exponentPow = 0;
|
||||||
|
bool scientificNotation = false;
|
||||||
|
while (i < bufSize)
|
||||||
|
{
|
||||||
|
scientificNotation = true;
|
||||||
|
char exponentCh = buf[i];
|
||||||
|
if (DqnChar_IsDigit(exponentCh))
|
||||||
|
{
|
||||||
|
exponentPow *= 10;
|
||||||
|
exponentPow += (buf[i] - '0');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i = bufSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(doyle): If exponent not specified but this branch occurred,
|
||||||
|
// the float string has a malformed scientific notation in the
|
||||||
|
// string, i.e. "e" followed by no number.
|
||||||
|
DQN_ASSERT(scientificNotation);
|
||||||
|
|
||||||
|
numDigitsAfterDecimal += exponentPow;
|
||||||
|
if (digitShiftIsPositive) digitShiftMultiplier = 10.0f;
|
||||||
|
}
|
||||||
|
else if (DqnChar_IsDigit(ch))
|
||||||
|
{
|
||||||
|
numDigitsAfterDecimal += (i32)isPastDecimal;
|
||||||
|
rawNumber *= 10;
|
||||||
|
rawNumber += (ch - '0');
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
numDigitsAfterDecimal += (i32)isPastDecimal;
|
|
||||||
rawNumber *= 10;
|
|
||||||
rawNumber += (ch - '0');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 digitShifter = 0.1f;
|
for (i32 i = 0; i < numDigitsAfterDecimal; i++)
|
||||||
const f32 INV_10 = 1.0f / 10.0f;
|
digitShiftValue *= digitShiftMultiplier;
|
||||||
for (i32 i = 0; i < numDigitsAfterDecimal-1; i++) digitShifter *= INV_10;
|
|
||||||
|
|
||||||
f32 result = (f32)rawNumber;
|
f32 result = (f32)rawNumber;
|
||||||
if (numDigitsAfterDecimal > 0)
|
if (numDigitsAfterDecimal > 0) result *= digitShiftValue;
|
||||||
{
|
|
||||||
result *= digitShifter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNegative) result *= -1;
|
if (isNegative) result *= -1;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -302,7 +302,15 @@ void StringsTest()
|
|||||||
f32 vP = Dqn_StrToF32(p, DQN_ARRAY_COUNT(p));
|
f32 vP = Dqn_StrToF32(p, DQN_ARRAY_COUNT(p));
|
||||||
DQN_ASSERT(DQN_ABS(vP) - DQN_ABS(1.25f) < EPSILON);
|
DQN_ASSERT(DQN_ABS(vP) - DQN_ABS(1.25f) < EPSILON);
|
||||||
|
|
||||||
printf("StringsTest(): StrToF32: Completed successfully\n");
|
const char q[] = "9.64635e-05";
|
||||||
|
f32 vQ = Dqn_StrToF32(q, DQN_ARRAY_COUNT(q));
|
||||||
|
DQN_ASSERT(DQN_ABS(vQ) - DQN_ABS(9.64635e-05) < EPSILON);
|
||||||
|
|
||||||
|
const char r[] = "9.64635e+05";
|
||||||
|
f32 vR = Dqn_StrToF32(q, DQN_ARRAY_COUNT(q));
|
||||||
|
DQN_ASSERT(DQN_ABS(vR) - DQN_ABS(9.64635e+05) < EPSILON);
|
||||||
|
|
||||||
|
printf("StringsTest(): StrToF32: Completed successfully\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user