Skip to content

Commit

Permalink
Parse doubles with boost::spirit::qi::long_double
Browse files Browse the repository at this point in the history
This works around an unaddressed spirit regression
(https://svn.boost.org/trac/boost/ticket/11608).

Fixes tidyverse#412
  • Loading branch information
jimhester committed Jun 15, 2016
1 parent 3b677d5 commit 4a5c5fe
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 3 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
@@ -1,5 +1,8 @@
# readr 0.2.2.9000

* Parse doubles with `boost::spirit::qi::long_double` to work around a bug in the
spirit library when parsing large numbers (#412, @jimhester).

* Supports reading into long vectors (#309, @jimhester).
* `default_locale()` now sets the default locale in `readr.default_locale`
rather than regenerating it for each call. (#416, @jimhester).
Expand Down
4 changes: 2 additions & 2 deletions src/QiParsers.h
Expand Up @@ -19,10 +19,10 @@ inline bool parseDouble(const char decimalMark, Iterator& first, Iterator& last,

if (decimalMark == '.') {
return boost::spirit::qi::parse(first, last,
boost::spirit::qi::double_, res);
boost::spirit::qi::long_double, res);
} else if (decimalMark == ',') {
return boost::spirit::qi::parse(first, last,
boost::spirit::qi::real_parser<double, DecimalCommaPolicy>(), res);
boost::spirit::qi::real_parser<long double, DecimalCommaPolicy>(), res);
} else {
return false;
}
Expand Down
14 changes: 13 additions & 1 deletion tests/testthat/test-parsing-numeric.R
Expand Up @@ -31,7 +31,7 @@ test_that("lone - or decimal marks are not numbers", {
test_that("Numbers with trailing characters are parsed as characters", {
expect_equal(collector_guess("13T"), "character")

expect_equal(collector_guess(collector_guess(c("13T","13T","10N"))), "character")
expect_equal(collector_guess(collector_guess(c("13T", "13T", "10N"))), "character")
})

# Leading zeros -----------------------------------------------------------
Expand Down Expand Up @@ -83,3 +83,15 @@ test_that("negative numbers return negative values", {

expect_equal(parse_number("-100,000.00"), -100000)
})

# Large numbers -------------------------------------------------------------

test_that("large numbers are parsed properly", {
expect_equal(parse_double("100000000000000000000"), 1e20)

expect_equal(parse_double("1267650600228229401496703205376"), 1.267650600228229401496703205376e+30)

expect_equal(parse_double("100000000000000000000", locale = es_MX), 1e20)

expect_equal(parse_double("1267650600228229401496703205376", locale = es_MX), 1.267650600228229401496703205376e+30)
})

0 comments on commit 4a5c5fe

Please sign in to comment.