Skip to content

Commit

Permalink
Fix #11
Browse files Browse the repository at this point in the history
  • Loading branch information
chainsawriot committed Jun 7, 2024
1 parent 94156d9 commit d84c806
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
21 changes: 17 additions & 4 deletions src/QiParsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define FASTREAD_QI_PARSERS

#include "Rinternals.h"
#include <ctype.h> // tolower

/*
An STL iterator-based string to floating point number conversion.
Expand All @@ -17,10 +18,10 @@ bsd_strtod(const char* begin, const char** endptr, const char decimal_mark) {
if (begin == *endptr) {
return NA_REAL;
}
if (*begin == 'n' || *begin == '?') {
*endptr = begin;
return NA_REAL;
}
// if (*begin == 'n' || *begin == '?') {
// *endptr = begin;
// return NA_REAL;
// }
int sign = 0, expSign = 0, i;
double fraction, dblExp;
const char* p;
Expand Down Expand Up @@ -93,6 +94,18 @@ bsd_strtod(const char* begin, const char** endptr, const char decimal_mark) {
} else if (p != *endptr && *p == '+')
++p;

// Code ported from vroom
/* NaN */
if (*endptr - p == 3 && tolower(p[0]) == 'n' && tolower(p[1]) == 'a' &&
tolower(p[2]) == 'n') {
return NAN;
}
/* Inf */
if (*endptr - p == 3 && tolower(p[0]) == 'i' && tolower(p[1]) == 'n' &&
tolower(p[2]) == 'f') {
return sign == 1 ? -HUGE_VAL : HUGE_VAL;
}

/* If we don't have a digit or decimal point something is wrong, so return an
* NA */
if (!(isdigit(*p) || *p == decimal_mark)) {
Expand Down
22 changes: 22 additions & 0 deletions tests/testthat/test-parsing-numeric.R
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,25 @@ test_that("scientific notation is parsed properly", {
expect_equal(parse_number("-17E-5-5"), -0.00017)
expect_equal(parse_number("1.2E-3"), 0.0012)
})

## Inf NAN NA ref gesistsa/minty#11

test_that("special cases", {
## Inf
expect_equal(parse_double("Inf"), Inf)
expect_equal(parse_double("INF"), Inf)
expect_equal(parse_double("-inf"), -Inf)
expect_equal(parse_double("-Inf"), -Inf)
expect_equal(parse_double("Infa"), NA_real_)
## NAN
expect_equal(parse_double("NAN"), NaN)
expect_equal(parse_double("Nan"), NaN)
expect_equal(parse_double("-nan"), NaN)
expect_equal(parse_double("-nan"), NaN)
expect_equal(parse_double("nana"), NA_real_)
## NA
expect_equal(parse_double("NA"), NA_real_)
expect_equal(parse_double("Naan"), NA_real_) ## in fact..
## integration
expect_equal(parse_double(c("NA", "NaN", "Inf", "3.14")), c(NA_real_, NaN, Inf, 3.14))
})

0 comments on commit d84c806

Please sign in to comment.