Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

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