diff options
author | David Robillard <d@drobilla.net> | 2019-12-18 20:05:18 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2020-10-27 13:13:58 +0100 |
commit | bf00e111df96c634f480eac9427238f99ac166d6 (patch) | |
tree | dfa68b6bae0dd5208f2814cdb9988848a1ba9a2e | |
parent | 00c7fe7bb9b7c409c3922431c9fefd348e4f8346 (diff) | |
download | serd-bf00e111df96c634f480eac9427238f99ac166d6.tar.gz serd-bf00e111df96c634f480eac9427238f99ac166d6.tar.bz2 serd-bf00e111df96c634f480eac9427238f99ac166d6.zip |
Add support for parsing NaN, INF, and -INF
-rw-r--r-- | src/string.c | 18 | ||||
-rw-r--r-- | tests/serd_test.c | 10 |
2 files changed, 24 insertions, 4 deletions
diff --git a/src/string.c b/src/string.c index 1e7e9348..9a6b4ff6 100644 --- a/src/string.c +++ b/src/string.c @@ -113,6 +113,19 @@ serd_strtod(const char* str, size_t* end) { double result = 0.0; +#define SET_END(index) do { if (end) { *end = index; } } while (0) + + if (!strcmp(str, "NaN")) { + SET_END(3); + return NAN; + } else if (!strcmp(str, "-INF")) { + SET_END(4); + return -INFINITY; + } else if (!strcmp(str, "INF")) { + SET_END(3); + return INFINITY; + } + // Point s at the first non-whitespace character const char* s = str; while (is_space(*s)) { ++s; } @@ -145,9 +158,6 @@ serd_strtod(const char* str, size_t* end) result *= pow(10, expt * expt_sign); } - if (end) { - *end = s - str; - } - + SET_END(s - str); return result * sign; } diff --git a/tests/serd_test.c b/tests/serd_test.c index a8853969..7f4c291b 100644 --- a/tests/serd_test.c +++ b/tests/serd_test.c @@ -209,6 +209,16 @@ test_read_string(void) static void test_string_to_double(void) { + size_t end = 0; + assert(isnan(serd_strtod("NaN", &end))); + assert(end == 3); + + assert(isinf(serd_strtod("INF", &end)) == 1); + assert(end == 3); + + assert(isinf(serd_strtod("-INF", &end)) == -1); + assert(end == 4); + const double expt_test_nums[] = { 2.0E18, -5e19, +8e20, 2e+24, -5e-5, 8e0, 9e-0, 2e+0 }; |