@@ -62,6 +62,9 @@ cdef extern from "headers/stdint.h":
6262cdef extern from " headers/portable.h" :
6363 pass
6464
65+ cdef extern from " errno.h" :
66+ int errno
67+
6568try :
6669 basestring
6770except NameError :
@@ -155,6 +158,7 @@ cdef extern from "parser/tokenizer.h":
155158
156159 void * skipset
157160 int skip_footer
161+ double (* converter)(const char * , char ** , char , char , char , int )
158162
159163 # error handling
160164 char * warn_msg
@@ -189,8 +193,13 @@ cdef extern from "parser/tokenizer.h":
189193 int64_t int_max, int * error, char tsep)
190194 uint64_t str_to_uint64(char * p_item, uint64_t uint_max, int * error)
191195
192- inline int to_double(char * item, double * p_value,
193- char sci, char decimal, char thousands)
196+ double xstrtod(const char * p, char ** q, char decimal, char sci,
197+ char tsep, int skip_trailing)
198+ double precise_xstrtod(const char * p, char ** q, char decimal, char sci,
199+ char tsep, int skip_trailing)
200+ double round_trip(const char * p, char ** q, char decimal, char sci,
201+ char tsep, int skip_trailing)
202+
194203 inline int to_complex(char * item, double * p_real,
195204 double * p_imag, char sci, char decimal)
196205 inline int to_longlong(char * item, long long * p_value)
@@ -315,7 +324,8 @@ cdef class TextReader:
315324 skip_footer = 0 ,
316325 verbose = False ,
317326 mangle_dupe_cols = True ,
318- tupleize_cols = False ):
327+ tupleize_cols = False ,
328+ float_precision = None ):
319329
320330 self .parser = parser_new()
321331 self .parser.chunksize = tokenize_chunksize
@@ -415,6 +425,11 @@ cdef class TextReader:
415425
416426 self .verbose = verbose
417427 self .low_memory = low_memory
428+ self .parser.converter = xstrtod
429+ if float_precision == ' high' :
430+ self .parser.converter = precise_xstrtod
431+ elif float_precision == ' round_trip' :
432+ self .parser.converter = round_trip
418433
419434 # encoding
420435 if encoding is not None :
@@ -1018,7 +1033,7 @@ cdef class TextReader:
10181033
10191034 elif dtype[1 ] == ' f' :
10201035 result, na_count = _try_double(self .parser, i, start, end,
1021- na_filter, na_hashset, na_flist)
1036+ na_filter, na_hashset, na_flist)
10221037
10231038 if dtype[1 :] != ' f8' :
10241039 result = result.astype(dtype)
@@ -1415,12 +1430,14 @@ cdef _try_double(parser_t *parser, int col, int line_start, int line_end,
14151430 size_t i, lines
14161431 coliter_t it
14171432 char * word
1433+ char * p_end
14181434 double * data
14191435 double NA = na_values[np.float64]
14201436 ndarray result
14211437 khiter_t k
14221438 bint use_na_flist = len (na_flist) > 0
14231439
1440+ global errno
14241441 lines = line_end - line_start
14251442 result = np.empty(lines, dtype = np.float64)
14261443 data = < double * > result.data
@@ -1436,8 +1453,9 @@ cdef _try_double(parser_t *parser, int col, int line_start, int line_end,
14361453 na_count += 1
14371454 data[0 ] = NA
14381455 else :
1439- error = to_double(word, data, parser.sci, parser.decimal, parser.thousands)
1440- if error != 1 :
1456+ data[0 ] = parser.converter(word, & p_end, parser.decimal, parser.sci,
1457+ parser.thousands, 1 )
1458+ if errno != 0 or p_end[0 ] or p_end == word:
14411459 if strcasecmp(word, cinf) == 0 :
14421460 data[0 ] = INF
14431461 elif strcasecmp(word, cneginf) == 0 :
@@ -1452,8 +1470,9 @@ cdef _try_double(parser_t *parser, int col, int line_start, int line_end,
14521470 else :
14531471 for i in range (lines):
14541472 word = COLITER_NEXT(it)
1455- error = to_double(word, data, parser.sci, parser.decimal, parser.thousands)
1456- if error != 1 :
1473+ data[0 ] = parser.converter(word, & p_end, parser.decimal, parser.sci,
1474+ parser.thousands, 1 )
1475+ if errno != 0 or p_end[0 ] or p_end == word:
14571476 if strcasecmp(word, cinf) == 0 :
14581477 data[0 ] = INF
14591478 elif strcasecmp(word, cneginf) == 0 :
0 commit comments