This is the mail archive of the libstdc++@sourceware.cygnus.com mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Extracting floating point numbers


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]