This is the mail archive of the
libstdc++@sourceware.cygnus.com
mailing list for the libstdc++ project.
Extracting floating point numbers
- To: Benjamin Kosnik <bkoz at cygnus dot com>
- Subject: Extracting floating point numbers
- From: Russell Davidson <russell at ehess dot cnrs-mrs dot fr>
- Date: Mon, 29 May 2000 22:02:58 +0200 (CEST)
- cc: libstdc++ at sourceware dot cygnus dot com
The stuff for extracting floating point numbers is still incomplete, and
can get confused by too many or too few signs and/or scientific-notation
exponents. I think that the following patch tidies that up. So far, at
least, I have not come up with an example for which it gives wrong
results.
After that, I include a short test function that could be included in
27_io/istream_extractor_arith.cc.
*** egcs/libstdc++-v3/bits/locale_facets.tcc.save Wed May 10 21:47:07 2000
--- locale_facets.tcc Mon May 29 13:11:36 2000
*************** namespace std
*** 312,338 ****
string __grp;
int __sep_pos = 0;
int __pos = 0;
! bool __testdec = false;
const char* __lits = __fmt->_S_literals;
while (__valid && __beg != __end)
{
__valid = false;
char __c = *__beg;
! char* __p = strchr(__fmt->_S_literals, __c);
// NB: strchr returns true for __c == 0x0
if (__p && __c)
{
! if ((__p >= &__lits[__cache_type::_S_digits + __base]
! && __p < &__lits[__cache_type::_S_digits_end]) ||
! (__p >= &__lits[__cache_type::_S_udigits+__base]
! && __p < &__lits[__cache_type::_S_udigits_end]))
{
! if (!(__fp && (__p == &__lits[__cache_type::_S_ee]
! || __p == &__lits[__cache_type::_S_Ee])))
! break;
}
__xtrc[__pos] = __c;
++__pos;
++__sep_pos;
--- 312,363 ----
string __grp;
int __sep_pos = 0;
int __pos = 0;
! bool __testdec = false, __testEE = false, __testsign = false;
! bool __testEEsign = false;
const char* __lits = __fmt->_S_literals;
while (__valid && __beg != __end)
{
__valid = false;
char __c = *__beg;
! const char* __p = strchr(__fmt->_S_literals, __c);
// NB: strchr returns true for __c == 0x0
if (__p && __c)
{
! // Check for sign and accept if appropriate
! if ((__p == &__lits[__cache_type::_S_minus]) ||
! (__p == &__lits[__cache_type::_S_plus]))
! {
! if (__testEE)
! {
! if (__testEEsign) break;
! __testEEsign = true;
! }
! else
! {
! if (__testsign) break;
! __testsign = true;
! }
! }
! // Check for exponential part and accept if appropriate
! else if ((__p == &__lits[__cache_type::_S_ee])
! || (__p == &__lits[__cache_type::_S_Ee]))
! {
! if (!__fp || __testEE || !__testsign) break;
! __testEE = true;
! }
! // Check for appropriate digits. If found, too late for a sign
! else if ((__p >= &__lits[__cache_type::_S_digits]
! && __p < &__lits[__cache_type::_S_digits+__base]) ||
! (__p >= &__lits[__cache_type::_S_udigits]
! && __p < &__lits[__cache_type::_S_udigits+__base]))
{
! __testsign = true;
! if (__testEE) __testEEsign = true;
}
+ // Nothing else will do
+ else break;
__xtrc[__pos] = __c;
++__pos;
++__sep_pos;
End of patch. The test:
bool test0x()
{
bool test = true;
std::string st("2.456e3-+0.567e-2");
std::stringbuf sb(st);
std::istream is(&sb);
double f1 = 0, f2 = 0;
char c;
(is>>std::ws) >> f1;
(is>>std::ws) >> c;
(is>>std::ws) >> f2;
test = f1 == 2456;
test &= f2 == 0.00567;
test &= c == '-';
#ifdef DEBUG_ASSERT
assert(test);
#endif
return test;
}
Russell.
Russell Davidson email: russell@ehess.cnrs-mrs.fr
GREQAM,
Centre de la Vieille Charite, telephone: +33-4.91.14.07.40
F-13002 Marseille fax: +33-4.91.90.02.27