aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2019-12-18 20:05:18 -0500
committerDavid Robillard <d@drobilla.net>2019-12-19 08:43:27 -0500
commit4693e2d0f4b6b218e059dbcf3fb0f49baaa072eb (patch)
treeb2105140e6fa9a581b5dc20a63c8e6e3891e606b
parent28de6689533914888093d32d3075f58e6f32a4a1 (diff)
downloadserd-4693e2d0f4b6b218e059dbcf3fb0f49baaa072eb.tar.gz
serd-4693e2d0f4b6b218e059dbcf3fb0f49baaa072eb.tar.bz2
serd-4693e2d0f4b6b218e059dbcf3fb0f49baaa072eb.zip
Add support for parsing NaN, INF, and -INF
-rw-r--r--src/string.c18
-rw-r--r--tests/serd_test.c10
2 files changed, 24 insertions, 4 deletions
diff --git a/src/string.c b/src/string.c
index 7229d6b2..d5899751 100644
--- a/src/string.c
+++ b/src/string.c
@@ -105,6 +105,19 @@ serd_strtod(const char* str, size_t* end)
{
double result = 0.0;
+#define SET_END(index) if (end) { *end = index; }
+
+ 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; }
@@ -137,10 +150,7 @@ 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 61a76864..c54f379f 100644
--- a/tests/serd_test.c
+++ b/tests/serd_test.c
@@ -178,6 +178,16 @@ test_string_to_double(void)
test_strtod(dbl, 1 / (double)MAX);
}
+ size_t end = 0;
+ assert(isnan(serd_strtod("NaN", &end)));
+ assert(end == 3);
+
+ assert(serd_strtod("INF", &end) == INFINITY);
+ assert(end == 3);
+
+ assert(serd_strtod("-INF", &end) == -INFINITY);
+ assert(end == 4);
+
const double expt_test_nums[] = {
2.0E18, -5e19, +8e20, 2e+24, -5e-5, 8e0, 9e-0, 2e+0
};