mirror of
https://github.com/bkaradzic/bx.git
synced 2026-02-17 20:52:37 +01:00
Added fromString.
This commit is contained in:
@@ -239,6 +239,9 @@ namespace bx
|
||||
///
|
||||
int32_t toString(char* _out, int32_t _max, uint64_t _value, uint32_t _base = 10);
|
||||
|
||||
///
|
||||
double fromString(const char* _str);
|
||||
|
||||
} // namespace bx
|
||||
|
||||
#include "inline/string.inl"
|
||||
|
||||
539
src/dtoa.cpp
539
src/dtoa.cpp
@@ -105,15 +105,15 @@ namespace bx
|
||||
|
||||
void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const
|
||||
{
|
||||
DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary();
|
||||
DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1);
|
||||
DiyFp pl = DiyFp( (f << 1) + 1, e - 1).NormalizeBoundary();
|
||||
DiyFp mi = (f == kDpHiddenBit) ? DiyFp( (f << 2) - 1, e - 2) : DiyFp( (f << 1) - 1, e - 1);
|
||||
mi.f <<= mi.e - pl.e;
|
||||
mi.e = pl.e;
|
||||
*plus = pl;
|
||||
*minus = mi;
|
||||
}
|
||||
|
||||
#define UINT64_C2(h, l) ((static_cast<uint64_t>(h) << 32) | static_cast<uint64_t>(l))
|
||||
#define UINT64_C2(h, l) ( (static_cast<uint64_t>(h) << 32) | static_cast<uint64_t>(l) )
|
||||
|
||||
static const int32_t kDiySignificandSize = 64;
|
||||
static const int32_t kDpSignificandSize = 52;
|
||||
@@ -217,10 +217,10 @@ namespace bx
|
||||
k++;
|
||||
}
|
||||
|
||||
uint32_t index = static_cast<uint32_t>((k >> 3) + 1);
|
||||
*K = -(-348 + static_cast<int32_t>(index << 3)); // decimal exponent no need lookup table
|
||||
uint32_t index = static_cast<uint32_t>( (k >> 3) + 1);
|
||||
*K = -(-348 + static_cast<int32_t>(index << 3) ); // decimal exponent no need lookup table
|
||||
|
||||
BX_CHECK(index < sizeof(s_kCachedPowers_F) / sizeof(s_kCachedPowers_F[0]));
|
||||
BX_CHECK(index < sizeof(s_kCachedPowers_F) / sizeof(s_kCachedPowers_F[0]) );
|
||||
return DiyFp(s_kCachedPowers_F[index], s_kCachedPowers_E[index]);
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ namespace bx
|
||||
{
|
||||
while (rest < wp_w
|
||||
&& delta - rest >= ten_kappa
|
||||
&& (rest + ten_kappa < wp_w || wp_w - rest > rest + ten_kappa - wp_w))
|
||||
&& (rest + ten_kappa < wp_w || wp_w - rest > rest + ten_kappa - wp_w) )
|
||||
{
|
||||
buffer[len - 1]--;
|
||||
rest += ten_kappa;
|
||||
@@ -256,7 +256,7 @@ namespace bx
|
||||
const DiyFp wp_w = Mp - W;
|
||||
uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
|
||||
uint64_t p2 = Mp.f & (one.f - 1);
|
||||
int32_t kappa = static_cast<int32_t>(CountDecimalDigit32(p1));
|
||||
int32_t kappa = static_cast<int32_t>(CountDecimalDigit32(p1) );
|
||||
*len = 0;
|
||||
|
||||
while (kappa > 0)
|
||||
@@ -557,4 +557,527 @@ namespace bx
|
||||
return toStringUnsigned(_dst, _max, _value, _base);
|
||||
}
|
||||
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2016 Grzegorz Kraszewski
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* IMPORTANT
|
||||
*
|
||||
* The code works in "round towards zero" mode. This is different from
|
||||
* GCC standard library strtod(), which uses "round half to even" rule.
|
||||
* Therefore it cannot be used as a direct drop-in replacement, as in
|
||||
* some cases results will be different on the least significant bit of
|
||||
* mantissa. Read more in the README.md file.
|
||||
*/
|
||||
|
||||
#define DIGITS 18
|
||||
|
||||
#define DOUBLE_PLUS_ZERO 0x0000000000000000ull
|
||||
#define DOUBLE_MINUS_ZERO 0x8000000000000000ull
|
||||
#define DOUBLE_PLUS_INFINITY 0x7ff0000000000000ull
|
||||
#define DOUBLE_MINUS_INFINITY 0xfff0000000000000ull
|
||||
|
||||
union HexDouble
|
||||
{
|
||||
double d;
|
||||
uint64_t u;
|
||||
};
|
||||
|
||||
#define lsr96(s2, s1, s0, d2, d1, d0) \
|
||||
d0 = ( (s0) >> 1) | ( ( (s1) & 1) << 31); \
|
||||
d1 = ( (s1) >> 1) | ( ( (s2) & 1) << 31); \
|
||||
d2 = (s2) >> 1;
|
||||
|
||||
#define lsl96(s2, s1, s0, d2, d1, d0) \
|
||||
d2 = ( (s2) << 1) | ( ( (s1) & (1 << 31) ) >> 31); \
|
||||
d1 = ( (s1) << 1) | ( ( (s0) & (1 << 31) ) >> 31); \
|
||||
d0 = (s0) << 1;
|
||||
|
||||
/*
|
||||
* Undefine the below constant if your processor or compiler is slow
|
||||
* at 64-bit arithmetic. This is a rare case however. 64-bit macros are
|
||||
* better for deeply pipelined CPUs (no conditional execution), are
|
||||
* very efficient for 64-bit processors and also fast on 32-bit processors
|
||||
* featuring extended precision arithmetic (x86, PowerPC_32, M68k and probably
|
||||
* more).
|
||||
*/
|
||||
|
||||
#define USE_64BIT_FOR_ADDSUB_MACROS 1
|
||||
|
||||
#if USE_64BIT_FOR_ADDSUB_MACROS
|
||||
|
||||
#define add96(s2, s1, s0, d2, d1, d0) { \
|
||||
uint64_t w; \
|
||||
w = (uint64_t)(s0) + (uint64_t)(d0); \
|
||||
(s0) = w; \
|
||||
w >>= 32; \
|
||||
w += (uint64_t)(s1) + (uint64_t)(d1); \
|
||||
(s1) = w; \
|
||||
w >>= 32; \
|
||||
w += (uint64_t)(s2) + (uint64_t)(d2); \
|
||||
(s2) = w; }
|
||||
|
||||
#define sub96(s2, s1, s0, d2, d1, d0) { \
|
||||
uint64_t w; \
|
||||
w = (uint64_t)(s0) - (uint64_t)(d0); \
|
||||
(s0) = w; \
|
||||
w >>= 32; \
|
||||
w += (uint64_t)(s1) - (uint64_t)(d1); \
|
||||
(s1) = w; \
|
||||
w >>= 32; \
|
||||
w += (uint64_t)(s2) - (uint64_t)(d2); \
|
||||
(s2) = w; }
|
||||
|
||||
#else
|
||||
|
||||
#define add96(s2, s1, s0, d2, d1, d0) { \
|
||||
uint32_t _x, _c; \
|
||||
_x = (s0); (s0) += (d0); \
|
||||
if ( (s0) < _x) _c = 1; else _c = 0; \
|
||||
_x = (s1); (s1) += (d1) + _c; \
|
||||
if ( ( (s1) < _x) || ( ( (s1) == _x) && _c) ) _c = 1; else _c = 0; \
|
||||
(s2) += (d2) + _c; }
|
||||
|
||||
#define sub96(s2, s1, s0, d2, d1, d0) { \
|
||||
uint32_t _x, _c; \
|
||||
_x = (s0); (s0) -= (d0); \
|
||||
if ( (s0) > _x) _c = 1; else _c = 0; \
|
||||
_x = (s1); (s1) -= (d1) + _c; \
|
||||
if ( ( (s1) > _x) || ( ( (s1) == _x) && _c) ) _c = 1; else _c = 0; \
|
||||
(s2) -= (d2) + _c; }
|
||||
|
||||
#endif /* USE_64BIT_FOR_ADDSUB_MACROS */
|
||||
|
||||
/* parser state machine states */
|
||||
|
||||
#define FSM_A 0
|
||||
#define FSM_B 1
|
||||
#define FSM_C 2
|
||||
#define FSM_D 3
|
||||
#define FSM_E 4
|
||||
#define FSM_F 5
|
||||
#define FSM_G 6
|
||||
#define FSM_H 7
|
||||
#define FSM_I 8
|
||||
#define FSM_STOP 9
|
||||
|
||||
/* Modify these if working with non-ASCII encoding */
|
||||
|
||||
#define DPOINT '.'
|
||||
#define ISEXP(x) ( ( (x) == 'E') || ( (x) == 'e') )
|
||||
|
||||
/* The structure is filled by parser, then given to converter. */
|
||||
struct PrepNumber
|
||||
{
|
||||
int negative; /* 0 if positive number, 1 if negative */
|
||||
int32_t exponent; /* power of 10 exponent */
|
||||
uint64_t mantissa; /* integer mantissa */
|
||||
};
|
||||
|
||||
/* Possible parser return values. */
|
||||
|
||||
#define PARSER_OK 0 // parser finished OK
|
||||
#define PARSER_PZERO 1 // no digits or number is smaller than +-2^-1022
|
||||
#define PARSER_MZERO 2 // number is negative, module smaller
|
||||
#define PARSER_PINF 3 // number is higher than +HUGE_VAL
|
||||
#define PARSER_MINF 4 // number is lower than -HUGE_VAL
|
||||
|
||||
/* GETC() macro gets next character from processed string. */
|
||||
|
||||
#define GETC(s) *s++
|
||||
|
||||
static int parser(const char *s, struct PrepNumber *pn)
|
||||
{
|
||||
int state = FSM_A;
|
||||
int digx = 0, c = ' '; /* initial value for kicking off the state machine */
|
||||
int result = PARSER_OK;
|
||||
int expneg = 0;
|
||||
int32_t expexp = 0;
|
||||
|
||||
while (state != FSM_STOP)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case FSM_A:
|
||||
if (isSpace(c) )
|
||||
{
|
||||
c = GETC(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
state = FSM_B;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSM_B:
|
||||
state = FSM_C;
|
||||
|
||||
if (c == '+')
|
||||
{
|
||||
c = GETC(s);
|
||||
}
|
||||
else if (c == '-')
|
||||
{
|
||||
pn->negative = 1;
|
||||
c = GETC(s);
|
||||
}
|
||||
else if (isNumeric(c) )
|
||||
{
|
||||
}
|
||||
else if (c == DPOINT)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
state = FSM_STOP;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSM_C:
|
||||
if (c == '0')
|
||||
{
|
||||
c = GETC(s);
|
||||
}
|
||||
else if (c == DPOINT)
|
||||
{
|
||||
c = GETC(s);
|
||||
state = FSM_D;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = FSM_E;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSM_D:
|
||||
if (c == '0')
|
||||
{
|
||||
c = GETC(s);
|
||||
if (pn->exponent > -2147483647) pn->exponent--;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = FSM_F;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSM_E:
|
||||
if (isNumeric(c) )
|
||||
{
|
||||
if (digx < DIGITS)
|
||||
{
|
||||
pn->mantissa *= 10;
|
||||
pn->mantissa += c - '0';
|
||||
digx++;
|
||||
}
|
||||
else if (pn->exponent < 2147483647)
|
||||
{
|
||||
pn->exponent++;
|
||||
}
|
||||
|
||||
c = GETC(s);
|
||||
}
|
||||
else if (c == DPOINT)
|
||||
{
|
||||
c = GETC(s);
|
||||
state = FSM_F;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = FSM_F;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSM_F:
|
||||
if (isNumeric(c) )
|
||||
{
|
||||
if (digx < DIGITS)
|
||||
{
|
||||
pn->mantissa *= 10;
|
||||
pn->mantissa += c - '0';
|
||||
pn->exponent--;
|
||||
digx++;
|
||||
}
|
||||
|
||||
c = GETC(s);
|
||||
}
|
||||
else if (ISEXP(c) )
|
||||
{
|
||||
c = GETC(s);
|
||||
state = FSM_G;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = FSM_G;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSM_G:
|
||||
if (c == '+')
|
||||
{
|
||||
c = GETC(s);
|
||||
}
|
||||
else if (c == '-')
|
||||
{
|
||||
expneg = 1;
|
||||
c = GETC(s);
|
||||
}
|
||||
|
||||
state = FSM_H;
|
||||
break;
|
||||
|
||||
case FSM_H:
|
||||
if (c == '0')
|
||||
{
|
||||
c = GETC(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
state = FSM_I;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSM_I:
|
||||
if (isNumeric(c) )
|
||||
{
|
||||
if (expexp < 214748364)
|
||||
{
|
||||
expexp *= 10;
|
||||
expexp += c - '0';
|
||||
}
|
||||
|
||||
c = GETC(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
state = FSM_STOP;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (expneg)
|
||||
{
|
||||
expexp = -expexp;
|
||||
}
|
||||
|
||||
pn->exponent += expexp;
|
||||
|
||||
if (pn->mantissa == 0)
|
||||
{
|
||||
if (pn->negative)
|
||||
{
|
||||
result = PARSER_MZERO;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = PARSER_PZERO;
|
||||
}
|
||||
}
|
||||
else if (pn->exponent > 309)
|
||||
{
|
||||
if (pn->negative)
|
||||
{
|
||||
result = PARSER_MINF;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = PARSER_PINF;
|
||||
}
|
||||
}
|
||||
else if (pn->exponent < -328)
|
||||
{
|
||||
if (pn->negative)
|
||||
{
|
||||
result = PARSER_MZERO;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = PARSER_PZERO;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static double converter(struct PrepNumber *pn)
|
||||
{
|
||||
int binexp = 92;
|
||||
union HexDouble hd;
|
||||
uint32_t s2, s1, s0; /* 96-bit precision integer */
|
||||
uint32_t q2, q1, q0; /* 96-bit precision integer */
|
||||
uint32_t r2, r1, r0; /* 96-bit precision integer */
|
||||
uint32_t mask28 = 0xF << 28;
|
||||
|
||||
hd.u = 0;
|
||||
|
||||
s0 = (uint32_t)(pn->mantissa & 0xFFFFFFFF);
|
||||
s1 = (uint32_t)(pn->mantissa >> 32);
|
||||
s2 = 0;
|
||||
|
||||
while (pn->exponent > 0)
|
||||
{
|
||||
lsl96(s2, s1, s0, q2, q1, q0); // q = p << 1
|
||||
lsl96(q2, q1, q0, r2, r1, r0); // r = p << 2
|
||||
lsl96(r2, r1, r0, s2, s1, s0); // p = p << 3
|
||||
add96(s2, s1, s0, q2, q1, q0); // p = (p << 3) + (p << 1)
|
||||
|
||||
pn->exponent--;
|
||||
|
||||
while (s2 & mask28)
|
||||
{
|
||||
lsr96(s2, s1, s0, q2, q1, q0);
|
||||
binexp++;
|
||||
s2 = q2;
|
||||
s1 = q1;
|
||||
s0 = q0;
|
||||
}
|
||||
}
|
||||
|
||||
while (pn->exponent < 0)
|
||||
{
|
||||
while (!(s2 & (1 << 31) ) )
|
||||
{
|
||||
lsl96(s2, s1, s0, q2, q1, q0);
|
||||
binexp--;
|
||||
s2 = q2;
|
||||
s1 = q1;
|
||||
s0 = q0;
|
||||
}
|
||||
|
||||
q2 = s2 / 10;
|
||||
r1 = s2 % 10;
|
||||
r2 = (s1 >> 8) | (r1 << 24);
|
||||
q1 = r2 / 10;
|
||||
r1 = r2 % 10;
|
||||
r2 = ( (s1 & 0xFF) << 16) | (s0 >> 16) | (r1 << 24);
|
||||
r0 = r2 / 10;
|
||||
r1 = r2 % 10;
|
||||
q1 = (q1 << 8) | ( (r0 & 0x00FF0000) >> 16);
|
||||
q0 = r0 << 16;
|
||||
r2 = (s0 & 0xFFFF) | (r1 << 16);
|
||||
q0 |= r2 / 10;
|
||||
s2 = q2;
|
||||
s1 = q1;
|
||||
s0 = q0;
|
||||
|
||||
pn->exponent++;
|
||||
}
|
||||
|
||||
if (s2 || s1 || s0)
|
||||
{
|
||||
while (!(s2 & mask28) )
|
||||
{
|
||||
lsl96(s2, s1, s0, q2, q1, q0);
|
||||
binexp--;
|
||||
s2 = q2;
|
||||
s1 = q1;
|
||||
s0 = q0;
|
||||
}
|
||||
}
|
||||
|
||||
binexp += 1023;
|
||||
|
||||
if (binexp > 2046)
|
||||
{
|
||||
if (pn->negative)
|
||||
{
|
||||
hd.u = DOUBLE_MINUS_INFINITY;
|
||||
}
|
||||
else
|
||||
{
|
||||
hd.u = DOUBLE_PLUS_INFINITY;
|
||||
}
|
||||
}
|
||||
else if (binexp < 1)
|
||||
{
|
||||
if (pn->negative)
|
||||
{
|
||||
hd.u = DOUBLE_MINUS_ZERO;
|
||||
}
|
||||
}
|
||||
else if (s2)
|
||||
{
|
||||
uint64_t q;
|
||||
uint64_t binexs2 = (uint64_t)binexp;
|
||||
|
||||
binexs2 <<= 52;
|
||||
q = ( (uint64_t)(s2 & ~mask28) << 24)
|
||||
| ( ( (uint64_t)s1 + 128) >> 8) | binexs2;
|
||||
|
||||
if (pn->negative)
|
||||
{
|
||||
q |= (1ULL << 63);
|
||||
}
|
||||
|
||||
hd.u = q;
|
||||
}
|
||||
|
||||
return hd.d;
|
||||
}
|
||||
|
||||
double fromString(const char* _str)
|
||||
{
|
||||
struct PrepNumber pn;
|
||||
union HexDouble hd;
|
||||
int i;
|
||||
double result;
|
||||
|
||||
pn.mantissa = 0;
|
||||
pn.negative = 0;
|
||||
pn.exponent = 0;
|
||||
hd.u = DOUBLE_PLUS_ZERO;
|
||||
|
||||
i = parser(_str, &pn);
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case PARSER_OK:
|
||||
result = converter(&pn);
|
||||
break;
|
||||
|
||||
case PARSER_PZERO:
|
||||
result = hd.d;
|
||||
break;
|
||||
|
||||
case PARSER_MZERO:
|
||||
hd.u = DOUBLE_MINUS_ZERO;
|
||||
result = hd.d;
|
||||
break;
|
||||
|
||||
case PARSER_PINF:
|
||||
hd.u = DOUBLE_PLUS_INFINITY;
|
||||
result = hd.d;
|
||||
break;
|
||||
|
||||
case PARSER_MINF:
|
||||
hd.u = DOUBLE_MINUS_INFINITY;
|
||||
result = hd.d;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace bx
|
||||
|
||||
@@ -182,6 +182,49 @@ TEST_CASE("toString double", "")
|
||||
REQUIRE(testToString(0.0000000001, "1e-10") );
|
||||
}
|
||||
|
||||
static bool testFromString(double _value, const char* _input)
|
||||
{
|
||||
char tmp[1024];
|
||||
int32_t num = bx::toString(tmp, BX_COUNTOF(tmp), _value);
|
||||
const double lhs = bx::fromString(tmp);
|
||||
const double rhs = bx::fromString(_input);
|
||||
|
||||
if (lhs == rhs)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
printf("result '%f', input '%s'\n", _value, _input);
|
||||
return false;
|
||||
}
|
||||
|
||||
TEST_CASE("fromString double", "")
|
||||
{
|
||||
REQUIRE(testFromString(0.0, "0.0") );
|
||||
REQUIRE(testFromString(-0.0, "-0.0") );
|
||||
REQUIRE(testFromString(1.0, "1.0") );
|
||||
REQUIRE(testFromString(-1.0, "-1.0") );
|
||||
REQUIRE(testFromString(1.2345, "1.2345") );
|
||||
REQUIRE(testFromString(1.2345678, "1.2345678") );
|
||||
REQUIRE(testFromString(0.123456789012, "0.123456789012") );
|
||||
REQUIRE(testFromString(1234567.8, "1234567.8") );
|
||||
REQUIRE(testFromString(-79.39773355813419, "-79.39773355813419") );
|
||||
REQUIRE(testFromString(0.000001, "0.000001") );
|
||||
REQUIRE(testFromString(0.0000001, "1e-7") );
|
||||
REQUIRE(testFromString(1e30, "1e30") );
|
||||
REQUIRE(testFromString(1.234567890123456e30, "1.234567890123456e30") );
|
||||
REQUIRE(testFromString(-5e-324, "-5e-324") );
|
||||
REQUIRE(testFromString(2.225073858507201e-308, "2.225073858507201e-308") );
|
||||
REQUIRE(testFromString(2.2250738585072014e-308, "2.2250738585072014e-308") );
|
||||
REQUIRE(testFromString(1.7976931348623157e308, "1.7976931348623157e308") );
|
||||
REQUIRE(testFromString(0.00000123123123, "0.00000123123123") );
|
||||
REQUIRE(testFromString(0.000000123123123, "1.23123123e-7") );
|
||||
REQUIRE(testFromString(123123.123, "123123.123") );
|
||||
REQUIRE(testFromString(1231231.23, "1231231.23") );
|
||||
REQUIRE(testFromString(0.000000000123123, "1.23123e-10") );
|
||||
REQUIRE(testFromString(0.0000000001, "1e-10") );
|
||||
}
|
||||
|
||||
TEST_CASE("StringView", "")
|
||||
{
|
||||
bx::StringView sv("test");
|
||||
|
||||
Reference in New Issue
Block a user