Aleph-w
3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
gmpfrxx.C
Go to the documentation of this file.
1
2
/*
3
Aleph_w
4
5
Data structures & Algorithms
6
version 2.0.0b
7
https://github.com/lrleon/Aleph-w
8
9
This file is part of Aleph-w library
10
11
Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13
Permission is hereby granted, free of charge, to any person obtaining a copy
14
of this software and associated documentation files (the "Software"), to deal
15
in the Software without restriction, including without limitation the rights
16
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
copies of the Software, and to permit persons to whom the Software is
18
furnished to do so, subject to the following conditions:
19
20
The above copyright notice and this permission notice shall be included in all
21
copies or substantial portions of the Software.
22
23
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
SOFTWARE.
30
*/
31
32
33
// this file implements the routines required by gmpfrxx.h
34
// it is modeled on mpfr-2.2.1/out_str.c
35
// gmp-4.2.1/mpz/set_f.c
36
// gmp-4.2.1/mpq/set_f.c
37
38
// (written by Jon Wilkening on Aug 8, 2007)
39
40
41
#include "
gmpfrxx.h
"
42
43
using namespace
std
;
44
45
46
// MpFrC is a dummy class holding the static members of mpfr_class
47
mpfr_rnd_t
MpFrC::rnd
= GMP_RNDN;
48
int
MpFrC::base
= 10;
49
50
51
istream &
operator>>
(istream &s, mpfr_ptr a) {
52
string
tmp;
53
s >> tmp;
54
mpfr_set_str(a, tmp.c_str(),
55
mpfr_class::get_base
(),
56
mpfr_class::get_rnd
());
57
// a = tmp.c_str();
58
return
s;
59
}
60
61
// modeled on mpfr-2.2.1/out_str.c
62
ostream &
operator<<
(ostream &os, mpfr_srcptr a)
63
{
64
char
*s, *t, *s0;
65
mp_exp_t e;
66
67
// for debugging:
68
// mpfr_out_str(stdout, 10, 0, a, RND); printf("\n");
69
70
if
(mpfr_nan_p(a)) {
71
os <<
"@NaN@"
;
72
return
os;
73
}
74
75
if
(mpfr_inf_p(a)) {
76
if
(MPFR_SIGN(a) > 0)
77
os <<
"@Inf@"
;
78
else
79
os <<
"-@Inf@"
;
80
return
os;
81
}
82
83
if
(mpfr_zero_p(a)) {
84
if
(MPFR_SIGN(a) > 0)
85
os <<
"0"
;
86
else
87
os <<
"-0"
;
88
return
os;
89
}
90
91
s = mpfr_get_str (
nullptr
, &e,
92
mpfr_class::get_base
(),
93
0, a,
94
mpfr_class::get_rnd
());
95
96
t = mpfr_get_str (
nullptr
, &e,
97
mpfr_class::get_base
(),
98
os.precision(), a,
99
mpfr_class::get_rnd
());
100
101
if
(strlen(s)<strlen(t))
102
mpfr_free_str(t);
103
else
{
104
mpfr_free_str(s);
105
s = t;
106
}
107
108
s0 = s;
109
/* for a=3.1416 we have s = "31416" and e = 1 */
110
111
if
(*s ==
'-'
)
112
os.put(*s++);
113
114
/* outputs mantissa */
115
os.put(*s++); e--;
/* leading digit */
116
os.put(
'.'
);
117
while
(*s !=
'\0'
)
118
os.put(*s++);
/* rest of mantissa */
119
120
mpfr_free_str(s0);
121
122
/* outputs exponent */
123
if
(e) {
124
os << (
mpfr_class::get_base
() <= 10 ?
'e'
:
'@'
) << (
long
) e;
125
}
126
127
return
os;
128
}
129
130
// fixme: it would be more efficient to work directly
131
// with the limbs, but I don't want to deal with the
132
// internal representations of both mpfr and gmp
133
void
mpz_set_mpfr
(mpz_ptr
w
, mpfr_srcptr u)
134
{
135
char
*s, *t;
136
long
k, sz;
137
mp_exp_t e;
138
139
// abs(u)<1 truncates to zero
140
if
( mpfr_get_exp(u)<=0 || mpfr_zero_p(u)
141
|| mpfr_nan_p(u) || mpfr_inf_p(u) ) {
142
mpz_set_ui(
w
, 0);
143
return
;
144
}
145
146
// note: this is done in hex to represent u exactly
147
// example: for u=3.1416 we have s = "31416" and e = 1
148
s = mpfr_get_str (
nullptr
, &e, 16, 0, u, GMP_RNDN);
149
sz = strlen(s);
150
151
if
(*s ==
'-'
)
152
e++;
153
154
if
(e<=sz) {
155
s[e] =
'\0'
;
// truncate
156
mpz_set_str(
w
, s, 16);
157
mpfr_free_str(s);
158
return
;
159
}
160
161
t = (
char
*) calloc(e+1,
sizeof
(
char
));
162
163
for
(k=0; k<sz; k++)
164
t[k] = s[k];
165
for
(k=sz; k<e; k++)
166
t[k] =
'0'
;
167
t[e] =
'\0'
;
168
169
mpz_set_str(
w
, t, 16);
170
free(t);
171
mpfr_free_str(s);
172
}
173
174
175
void
mpq_set_mpfr
(mpq_ptr
w
, mpfr_srcptr u)
176
{
177
char
*s, *t;
178
long
k, sz;
179
mp_exp_t e, bits;
180
181
if
( mpfr_zero_p(u) || mpfr_nan_p(u) || mpfr_inf_p(u) ) {
182
mpq_set_ui(
w
, 0, 1);
183
return
;
184
}
185
186
// note: this is done in binary to represent u exactly
187
// example: u=10.1001 --> s = "101001", e = 2
188
s = mpfr_get_str (
nullptr
, &e, 2, 0, u, GMP_RNDN);
189
sz = strlen(s);
190
191
t = s+sz;
192
while
(*(--t) ==
'0'
)
193
*t =
'\0'
;
// trim trailing zeros
194
195
sz = strlen(s);
196
bits = (*s ==
'-'
) ? sz-1 : sz;
// bits>0 since u!=0
197
198
if
(e>=bits) {
199
e = sz+e-bits;
200
// no denominator needed
201
t = (
char
*) malloc((e+1)*
sizeof
(char));
202
strcpy(t,s);
203
for
(k=sz; k<e; k++)
204
t[k] =
'0'
;
205
t[e] =
'\0'
;
206
mpq_set_str(
w
, t, 2);
207
free(t);
208
mpfr_free_str(s);
209
return
;
210
}
211
212
e = sz+bits-e+2;
213
t = (
char
*) malloc((e+1)*
sizeof
(char));
214
strcpy(t,s);
215
t[sz++] =
'/'
;
216
t[sz++] =
'1'
;
217
for
(k=sz; k<e; k++)
218
t[k] =
'0'
;
219
t[e] =
'\0'
;
220
mpq_set_str(
w
, t, 2);
221
free(t);
222
mpfr_free_str(s);
223
}
w
long double w
Definition
btreepic.C:153
MpFrC::base
static int base
Definition
gmpfrxx.h:102
MpFrC::get_base
static int get_base()
Definition
gmpfrxx.h:104
MpFrC::get_rnd
static mpfr_rnd_t get_rnd()
Definition
gmpfrxx.h:106
MpFrC::rnd
static mpfr_rnd_t rnd
Definition
gmpfrxx.h:101
operator>>
istream & operator>>(istream &s, mpfr_ptr a)
Definition
gmpfrxx.C:51
mpz_set_mpfr
void mpz_set_mpfr(mpz_ptr w, mpfr_srcptr u)
Definition
gmpfrxx.C:133
mpq_set_mpfr
void mpq_set_mpfr(mpq_ptr w, mpfr_srcptr u)
Definition
gmpfrxx.C:175
operator<<
ostream & operator<<(ostream &os, mpfr_srcptr a)
Definition
gmpfrxx.C:62
gmpfrxx.h
std
STL namespace.
gmpfrxx.C
Generated by
1.9.8