ismpf.cc
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:3k
源码类别:

数学计算

开发平台:

Unix_Linux

  1. /* operator>> -- C++-style input of mpf_t.
  2. Copyright 2001, 2003 Free Software Foundation, Inc.
  3. This file is part of the GNU MP Library.
  4. The GNU MP Library is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or (at your
  7. option) any later version.
  8. The GNU MP Library is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  11. License for more details.
  12. You should have received a copy of the GNU Lesser General Public License
  13. along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
  14. #include <cctype>
  15. #include <iostream>
  16. #include <string>
  17. #include <clocale>    // for localeconv
  18. #include "gmp.h"
  19. #include "gmp-impl.h"
  20. using namespace std;
  21. // For g++ libstdc++ parsing see num_get<chartype,initer>::_M_extract_float
  22. // in include/bits/locale_facets.tcc.
  23. //
  24. // There are no plans to accept hex or octal floats, not unless the standard
  25. // C++ library does so.  Although such formats might be of use, it's
  26. // considered more important to be compatible with what the normal
  27. // operator>> does on "double"s etc.
  28. istream &
  29. operator>> (istream &i, mpf_ptr f)
  30. {
  31.   int base;
  32.   char c = 0;
  33.   string s;
  34.   bool ok = false;
  35.   // C decimal point, as expected by mpf_set_str
  36.   const char *lconv_point = localeconv()->decimal_point;
  37.   // C++ decimal point
  38. #if HAVE_STD__LOCALE
  39.   const locale& loc = i.getloc();
  40.   char point_char = use_facet< numpunct<char> >(loc).decimal_point();
  41. #else
  42.   const char *point = lconv_point;
  43.   char point_char = *point;
  44. #endif
  45.   i.get(c); // start reading
  46.   if (i.flags() & ios::skipws) // skip initial whitespace
  47.     {
  48.       // C++ isspace
  49. #if HAVE_STD__LOCALE
  50.       const ctype<char>& ct = use_facet< ctype<char> >(loc);
  51. #define cxx_isspace(c)  (ct.is(ctype_base::space,(c)))
  52. #else
  53. #define cxx_isspace(c)  isspace(c)
  54. #endif
  55.       while (cxx_isspace(c) && i.get(c))
  56.         ;
  57.     }
  58.   if (c == '-' || c == '+') // sign
  59.     {
  60.       if (c == '-')
  61. s = "-";
  62.       i.get(c);
  63.     }
  64.   base = 10;
  65.   __gmp_istream_set_digits(s, i, c, ok, base); // read the number
  66.   // look for the C++ radix point, but put the C one in for mpf_set_str
  67.   if (c == point_char)
  68.     {
  69. #if HAVE_STD__LOCALE
  70.       i.get(c);
  71. #else // lconv point can be multi-char
  72.       for (;;)
  73.         {
  74.           i.get(c);
  75.           point++;
  76.           if (*point == '')
  77.             break;
  78.           if (c != *point)
  79.             goto fail;
  80.         }
  81. #endif
  82.       s += lconv_point;
  83.       __gmp_istream_set_digits(s, i, c, ok, base); // read the mantissa
  84.     }
  85.   if (ok && (c == 'e' || c == 'E')) // exponent
  86.     {
  87.       s += c;
  88.       i.get(c);
  89.       ok = false; // exponent is mandatory
  90.       if (c == '-' || c == '+') // sign
  91. {
  92.   s += c;
  93.   i.get(c);
  94. }
  95.       __gmp_istream_set_digits(s, i, c, ok, base); // read the exponent
  96.     }
  97.   if (i.good()) // last character read was non-numeric
  98.     i.putback(c);
  99.   else if (i.eof() && ok) // stopped just before eof
  100.     i.clear();
  101.   if (ok)
  102.     ASSERT_NOCARRY (mpf_set_str(f, s.c_str(), base)); // extract the number
  103.   else
  104.     {
  105.     fail:
  106.       i.setstate(ios::failbit); // read failed
  107.     }
  108.   return i;
  109. }