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
43using namespace std;
44
45
46// MpFrC is a dummy class holding the static members of mpfr_class
47mpfr_rnd_t MpFrC::rnd = GMP_RNDN;
48int MpFrC::base = 10;
49
50
51istream & operator>>(istream &s, mpfr_ptr a) {
52 string tmp;
53 s >> tmp;
54 mpfr_set_str(a, tmp.c_str(),
57 // a = tmp.c_str();
58 return s;
59}
60
61// modeled on mpfr-2.2.1/out_str.c
62ostream & 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,
93 0, a,
95
96 t = mpfr_get_str (nullptr, &e,
98 os.precision(), a,
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
133void 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
175void 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}
long double w
Definition btreepic.C:153
static int base
Definition gmpfrxx.h:102
static int get_base()
Definition gmpfrxx.h:104
static mpfr_rnd_t get_rnd()
Definition gmpfrxx.h:106
static mpfr_rnd_t rnd
Definition gmpfrxx.h:101
istream & operator>>(istream &s, mpfr_ptr a)
Definition gmpfrxx.C:51
void mpz_set_mpfr(mpz_ptr w, mpfr_srcptr u)
Definition gmpfrxx.C:133
void mpq_set_mpfr(mpq_ptr w, mpfr_srcptr u)
Definition gmpfrxx.C:175
ostream & operator<<(ostream &os, mpfr_srcptr a)
Definition gmpfrxx.C:62
STL namespace.