rust_mpfr/
mpfr.rs

1use gmp::mpf::{Mpf, mpf_ptr, mpf_srcptr};
2use gmp::mpq::{Mpq, mpq_srcptr};
3use gmp::mpz::{Mpz, mpz_ptr, mpz_srcptr};
4use libc::{c_char, c_int, c_ulong, c_long, c_double, c_void, size_t};
5use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
6use std::ffi::CStr;
7use std::cmp::{Eq, PartialEq, Ord, PartialOrd, Ordering};
8use std::cmp;
9use std::convert::{From, Into};
10use std::ffi::CString;
11use std::fmt;
12use std::mem::uninitialized;
13use std::ops::{Add, Sub, Mul, Div, Neg};
14use std::str;
15use std::ptr;
16
17type mpfr_prec_t = c_long;
18type mpfr_sign_t = c_int;
19type mpfr_exp_t = c_long;
20
21#[repr(C)]
22pub enum mpfr_rnd_t {
23    MPFR_RNDN = 0, // round to nearest, with ties to even
24    MPFR_RNDZ, // round toward zero
25    MPFR_RNDU, // round toward +Inf
26    MPFR_RNDD, // round toward -Inf
27    MPFR_RNDA, // round away from zero
28    MPFR_RNDF, // faithful rounding (not implemented yet)
29    MPFR_RNDNA = -1, // round to nearest, with ties away from zero (mpfr_rouund)
30}
31
32#[repr(C)]
33pub struct mpfr_struct {
34    _mpfr_prec: mpfr_prec_t,
35    _mpfr_sign: mpfr_sign_t,
36    _mpfr_exp: mpfr_exp_t,
37    _mpfr_d: *mut c_void,
38}
39
40pub type mpfr_srcptr = *const mpfr_struct;
41pub type mpfr_ptr = *mut mpfr_struct;
42
43#[link(name = "mpfr")]
44extern {
45    // Initialization
46    fn mpfr_init(x: mpfr_ptr);
47    fn mpfr_init2(x: mpfr_ptr, prec: mpfr_prec_t);
48    fn mpfr_clear(x: mpfr_ptr);
49    fn mpfr_set_default_prec(prec: mpfr_prec_t);
50    fn mpfr_get_default_prec() -> mpfr_prec_t;
51    fn mpfr_set_prec(x: mpfr_ptr, prec: mpfr_prec_t);
52    fn mpfr_get_prec(x: mpfr_srcptr) -> mpfr_prec_t;
53
54    // Assignment
55    fn mpfr_set(rop: mpfr_ptr, op: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
56    fn mpfr_set_ui(rop: mpfr_ptr, op: c_ulong, rnd: mpfr_rnd_t) -> c_int;
57    fn mpfr_set_si(rop: mpfr_ptr, op: c_long, rnd: mpfr_rnd_t) -> c_int;
58    fn mpfr_set_d(rop: mpfr_ptr, op: c_double, rnd: mpfr_rnd_t) -> c_int;
59    fn mpfr_set_z(rop: mpfr_ptr, op: mpz_srcptr, rnd: mpfr_rnd_t) -> c_int;
60    fn mpfr_set_q(rop: mpfr_ptr, op: mpq_srcptr, rnd: mpfr_rnd_t) -> c_int;
61    fn mpfr_set_f(rop: mpfr_ptr, op: mpf_srcptr, rnd: mpfr_rnd_t) -> c_int;
62    fn mpfr_set_ui_2exp(rop: mpfr_ptr, op: c_ulong, e: mpfr_exp_t, rnd: mpfr_rnd_t) -> c_int;
63    fn mpfr_set_si_2exp(rop: mpfr_ptr, op: c_long, e: mpfr_exp_t, rnd: mpfr_rnd_t) -> c_int;
64    fn mpfr_set_z_2exp(rop: mpfr_ptr, op: mpz_srcptr, e: mpfr_exp_t, rnd: mpfr_rnd_t) -> c_int;
65    fn mpfr_set_nan(x: mpfr_ptr);
66    fn mpfr_set_inf(x: mpfr_ptr, sign: c_int);
67    fn mpfr_set_zero(x: mpfr_ptr, sign: c_int);
68    fn mpfr_set_str(rop: mpfr_ptr, s: *const c_char, base: c_int, rnd: mpfr_rnd_t) -> c_int;
69
70    // Conversion
71    fn mpfr_get_ui(op: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_ulong;
72    fn mpfr_get_si(op: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_long;
73    fn mpfr_get_d(op: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_double;
74    fn mpfr_get_z(rop: mpz_ptr, op: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
75    fn mpfr_get_f(rop: mpf_ptr, op: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
76
77    // Comparison
78    fn mpfr_cmp(op1: mpfr_srcptr, op2: mpfr_srcptr) -> c_int;
79    fn mpfr_cmp_ui(op1: mpfr_srcptr, op2: c_ulong) -> c_int;
80
81    // Arithmetic
82    fn mpfr_add(rop: mpfr_ptr, op1: mpfr_srcptr, op2: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
83    fn mpfr_add_d(rop: mpfr_ptr, op1: mpfr_srcptr, op2: c_double, rnd: mpfr_rnd_t) -> c_int;
84    fn mpfr_add_si(rop: mpfr_ptr, op1: mpfr_srcptr, op2: c_long, rnd: mpfr_rnd_t) -> c_int;
85    fn mpfr_sub(rop: mpfr_ptr, op1: mpfr_srcptr, op2: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
86    fn mpfr_sub_d(rop: mpfr_ptr, op1: mpfr_srcptr, op2: c_double, rnd: mpfr_rnd_t) -> c_int;
87    fn mpfr_sub_si(rop: mpfr_ptr, op1: mpfr_srcptr, op2: c_long, rnd: mpfr_rnd_t) -> c_int;
88    fn mpfr_d_sub(rop: mpfr_ptr, op1: c_double, op2: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
89    fn mpfr_si_sub(rop: mpfr_ptr, op1: c_long, op2: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
90    fn mpfr_mul(rop: mpfr_ptr, op1: mpfr_srcptr, op2: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
91    fn mpfr_mul_d(rop: mpfr_ptr, op1: mpfr_srcptr, op2: c_double, rnd: mpfr_rnd_t) -> c_int;
92    fn mpfr_mul_si(rop: mpfr_ptr, op1: mpfr_srcptr, op2: c_long, rnd: mpfr_rnd_t) -> c_int;
93    fn mpfr_div(rop: mpfr_ptr, op1: mpfr_srcptr, op2: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
94    fn mpfr_div_d(rop: mpfr_ptr, op1: mpfr_srcptr, op2: c_double, rnd: mpfr_rnd_t) -> c_int;
95    fn mpfr_div_si(rop: mpfr_ptr, op1: mpfr_srcptr, op2: c_long, rnd: mpfr_rnd_t) -> c_int;
96    fn mpfr_d_div(rop: mpfr_ptr, op1: c_double, op2: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
97    fn mpfr_si_div(rop: mpfr_ptr, op1: c_long, op2: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
98    fn mpfr_neg(rop: mpfr_ptr, op: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
99
100    // Rounding
101    fn mpfr_floor(rop: mpfr_ptr, op: mpfr_srcptr) -> c_int;
102    fn mpfr_ceil(rop: mpfr_ptr, op: mpfr_srcptr) -> c_int;
103    fn mpfr_round(rop: mpfr_ptr, op: mpfr_srcptr) -> c_int;
104
105    // Functions
106    fn mpfr_sqrt(rop: mpfr_ptr, op: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
107    fn mpfr_cbrt(rop: mpfr_ptr, op: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
108    fn mpfr_root(rop: mpfr_ptr, op: mpfr_srcptr, k: c_ulong, rnd: mpfr_rnd_t) -> c_int;
109    fn mpfr_pow(rop: mpfr_ptr, op1: mpfr_srcptr, op2: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
110    fn mpfr_abs(rop: mpfr_ptr, op: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
111    fn mpfr_exp(rop: mpfr_ptr, op: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
112    fn mpfr_log(rop: mpfr_ptr, op: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
113    fn mpfr_gamma(rop: mpfr_ptr, op: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
114    fn mpfr_lngamma(rop: mpfr_ptr, op: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
115    fn mpfr_lgamma(rop: mpfr_ptr, op: mpfr_srcptr, rnd: mpfr_rnd_t) -> c_int;
116
117    // Formatted output
118    fn mpfr_snprintf(buffer: *const c_char, length: size_t, string: *const u8, ...) -> c_int;
119}
120
121pub struct Mpfr {
122    pub mpfr: mpfr_struct,
123}
124
125impl fmt::Debug for Mpfr {
126    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
127        fmt::Display::fmt(&self, fmt)
128    }
129}
130
131impl fmt::Display for Mpfr {
132    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
133        unsafe {
134            let length = mpfr_snprintf(ptr::null(), 0, b"%.Re\0".as_ptr(), &self.mpfr);
135            if length < 0 {
136                // Maybe fmt.write_str("@uninnitialized@")
137                return Ok(())
138            }
139            let buff: Vec<c_char> = Vec::with_capacity((length + 1) as usize);
140            mpfr_snprintf(buff.as_ptr(),
141                          (length + 1) as size_t,
142                          b"%.Re\0".as_ptr(),
143                          &self.mpfr);
144            let s = CStr::from_ptr(buff.as_ptr());
145            fmt.write_str(str::from_utf8_unchecked(s.to_bytes()))
146        }
147    }
148}
149
150unsafe impl Send for Mpfr { }
151
152impl Drop for Mpfr {
153    fn drop(&mut self) {
154        unsafe { mpfr_clear(&mut self.mpfr) }
155    }
156}
157
158impl Clone for Mpfr {
159    fn clone(&self) -> Mpfr {
160        let mut mpfr = Mpfr::new2(self.get_prec());
161        mpfr.set(self);
162        mpfr
163    }
164}
165
166impl Mpfr {
167    pub fn new() -> Mpfr {
168        unsafe {
169            let mut mpfr = uninitialized();
170            mpfr_init(&mut mpfr);
171            Mpfr { mpfr: mpfr }
172        }
173    }
174
175    pub fn new2(precision: usize) -> Mpfr {
176        unsafe {
177            let mut mpfr = uninitialized();
178            mpfr_init2(&mut mpfr, precision as mpfr_prec_t);
179            Mpfr { mpfr: mpfr }
180        }
181    }
182
183    pub fn new_from_str<T: Into<Vec<u8>>>(s: T, base: usize) -> Option<Mpfr> {
184        let c_string = match CString::new(s) {
185            Ok(c_string) => c_string,
186            Err(..) => return None,
187        };
188        unsafe {
189            let mut mpfr = Mpfr::new();
190            if mpfr_set_str(&mut mpfr.mpfr,
191                            c_string.as_ptr(),
192                            base as c_int,
193                            mpfr_rnd_t::MPFR_RNDN) == 0 {
194                Some(mpfr)
195            } else {
196                None
197            }
198        }
199    }
200
201    pub fn new2_from_str<T: Into<Vec<u8>>>(precision: usize, s: T, base: usize) -> Option<Mpfr> {
202        let c_string = match CString::new(s) {
203            Ok(c_string) => c_string,
204            Err(..) => return None,
205        };
206        unsafe {
207            let mut mpfr = Mpfr::new2(precision);
208            if mpfr_set_str(&mut mpfr.mpfr,
209                            c_string.as_ptr(),
210                            base as c_int,
211                            mpfr_rnd_t::MPFR_RNDN) == 0 {
212                Some(mpfr)
213            } else {
214                None
215            }
216        }
217    }
218
219    pub fn set(&mut self, other: &Mpfr) {
220        unsafe {
221            mpfr_set(&mut self.mpfr, &other.mpfr, mpfr_rnd_t::MPFR_RNDN);
222        }
223    }
224
225    pub fn new_u64_2exp(base: u64, exp: i32) -> Mpfr {
226        unsafe {
227            let mut mpfr = Mpfr::new();
228            mpfr_set_ui_2exp(&mut mpfr.mpfr,
229                             base as c_ulong,
230                             exp as mpfr_exp_t,
231                             mpfr_rnd_t::MPFR_RNDN);
232            mpfr
233        }
234    }
235
236    pub fn new_i64_2exp(base: i64, exp: i32) -> Mpfr {
237        unsafe {
238            let mut mpfr = Mpfr::new();
239            mpfr_set_si_2exp(&mut mpfr.mpfr,
240                             base as c_long,
241                             exp as mpfr_exp_t,
242                             mpfr_rnd_t::MPFR_RNDN);
243            mpfr
244        }
245    }
246
247    pub fn new_mpz_2exp(base: &Mpz, exp: i32) -> Mpfr {
248        unsafe {
249            let mut mpfr = Mpfr::new();
250            mpfr_set_z_2exp(&mut mpfr.mpfr,
251                            base.inner(),
252                            exp as mpfr_exp_t,
253                            mpfr_rnd_t::MPFR_RNDN);
254            mpfr
255        }
256    }
257
258    pub fn zero(sign: i32) -> Mpfr {
259        unsafe {
260            let mut mpfr = Mpfr::new();
261            mpfr_set_zero(&mut mpfr.mpfr, sign as c_int);
262            mpfr
263        }
264    }
265
266    pub fn inf(sign: i32) -> Mpfr {
267        unsafe {
268            let mut mpfr = Mpfr::new();
269            mpfr_set_inf(&mut mpfr.mpfr, sign as c_int);
270            mpfr
271        }
272    }
273
274    pub fn nan() -> Mpfr {
275        unsafe {
276            let mut mpfr = Mpfr::new();
277            mpfr_set_nan(&mut mpfr.mpfr);
278            mpfr
279        }
280    }
281
282    pub fn get_default_prec() -> usize {
283        unsafe { mpfr_get_default_prec() as usize }
284    }
285
286    pub fn set_default_prec(precision: usize) {
287        unsafe {
288            mpfr_set_default_prec(precision as mpfr_prec_t);
289        }
290    }
291
292    pub fn get_prec(&self) -> usize {
293        unsafe { mpfr_get_prec(&self.mpfr) as usize }
294    }
295
296    pub fn set_prec(&mut self, precision: usize) {
297        unsafe {
298            mpfr_set_prec(&mut self.mpfr, precision as mpfr_prec_t);
299        }
300    }
301
302    // Rounding
303
304    pub fn floor(&self) -> Mpfr {
305        unsafe {
306            let mut res = Mpfr::new2(self.get_prec());
307            mpfr_floor(&mut res.mpfr, &self.mpfr);
308            res
309        }
310    }
311
312    pub fn ceil(&self) -> Mpfr {
313        unsafe {
314            let mut res = Mpfr::new2(self.get_prec());
315            mpfr_ceil(&mut res.mpfr, &self.mpfr);
316            res
317        }
318    }
319
320    pub fn round(&self) -> Mpfr {
321        unsafe {
322            let mut res = Mpfr::new2(self.get_prec());
323            mpfr_round(&mut res.mpfr, &self.mpfr);
324            res
325        }
326    }
327
328    // Mathematical functions
329
330    pub fn sqrt(&self) -> Mpfr {
331        unsafe {
332            let mut res = Mpfr::new2(self.get_prec());
333            mpfr_sqrt(&mut res.mpfr, &self.mpfr, mpfr_rnd_t::MPFR_RNDN);
334            res
335        }
336    }
337
338    pub fn cbrt(&self) -> Mpfr {
339        unsafe {
340            let mut res = Mpfr::new2(self.get_prec());
341            mpfr_cbrt(&mut res.mpfr, &self.mpfr, mpfr_rnd_t::MPFR_RNDN);
342            res
343        }
344    }
345
346    pub fn root(&self, k: u64) -> Mpfr {
347        unsafe {
348            let mut res = Mpfr::new2(self.get_prec());
349            mpfr_root(&mut res.mpfr,
350                      &self.mpfr,
351                      k as c_ulong,
352                      mpfr_rnd_t::MPFR_RNDN);
353            res
354        }
355    }
356
357    pub fn pow(&self, other: &Mpfr) -> Mpfr {
358        unsafe {
359            let mut res = Mpfr::new2(self.get_prec());
360            mpfr_pow(&mut res.mpfr,
361                     &self.mpfr,
362                     &other.mpfr,
363                     mpfr_rnd_t::MPFR_RNDN);
364            res
365        }
366    }
367
368    pub fn abs(&self) -> Mpfr {
369        unsafe {
370            let mut res = Mpfr::new2(self.get_prec());
371            mpfr_abs(&mut res.mpfr, &self.mpfr, mpfr_rnd_t::MPFR_RNDN);
372            res
373        }
374    }
375
376    pub fn exp(&self) -> Mpfr {
377        unsafe {
378            let mut res = Mpfr::new2(self.get_prec());
379            mpfr_exp(&mut res.mpfr, &self.mpfr, mpfr_rnd_t::MPFR_RNDN);
380            res
381        }
382    }
383
384    pub fn log(&self) -> Mpfr {
385        unsafe {
386            let mut res = Mpfr::new2(self.get_prec());
387            mpfr_log(&mut res.mpfr, &self.mpfr, mpfr_rnd_t::MPFR_RNDN);
388            res
389        }
390    }
391
392    pub fn gamma(&self) -> Mpfr {
393        unsafe {
394            let mut res = Mpfr::new2(self.get_prec());
395            mpfr_gamma(&mut res.mpfr, &self.mpfr, mpfr_rnd_t::MPFR_RNDN);
396            res
397        }
398    }
399
400    pub fn lngamma(&self) -> Mpfr {
401        unsafe {
402            let mut res = Mpfr::new2(self.get_prec());
403            mpfr_lngamma(&mut res.mpfr, &self.mpfr, mpfr_rnd_t::MPFR_RNDN);
404            res
405        }
406    }
407
408    pub fn lgamma(&self) -> Mpfr {
409        unsafe {
410            let mut res = Mpfr::new2(self.get_prec());
411            mpfr_lgamma(&mut res.mpfr, &self.mpfr, mpfr_rnd_t::MPFR_RNDN);
412            res
413        }
414    }
415}
416
417impl Eq for Mpfr { }
418impl PartialEq for Mpfr {
419    fn eq(&self, other: &Mpfr) -> bool {
420        unsafe { mpfr_cmp(&self.mpfr, &other.mpfr) == 0 }
421    }
422}
423
424impl Ord for Mpfr {
425    fn cmp(&self, other: &Mpfr) -> Ordering {
426        let cmp = unsafe { mpfr_cmp(&self.mpfr, &other.mpfr) };
427        if cmp == 0 {
428            Ordering::Equal
429        } else if cmp > 0 {
430            Ordering::Greater
431        } else {
432            Ordering::Less
433        }
434    }
435}
436
437impl PartialOrd for Mpfr {
438    fn partial_cmp(&self, other: &Mpfr) -> Option<Ordering> {
439        Some(self.cmp(other))
440    }
441}
442
443// Conversions
444
445impl From<i64> for Mpfr {
446    fn from(x: i64) -> Mpfr {
447        unsafe {
448            let mut mpfr = Mpfr::new();
449            mpfr_set_si(&mut mpfr.mpfr, x as c_long, mpfr_rnd_t::MPFR_RNDN);
450            mpfr
451        }
452    }
453}
454
455impl From<u64> for Mpfr {
456    fn from(x: u64) -> Mpfr {
457        unsafe {
458            let mut mpfr = Mpfr::new();
459            mpfr_set_ui(&mut mpfr.mpfr, x as c_ulong, mpfr_rnd_t::MPFR_RNDN);
460            mpfr
461        }
462    }
463}
464
465impl From<f64> for Mpfr {
466    fn from(x: f64) -> Mpfr {
467        unsafe {
468            let mut mpfr = Mpfr::new();
469            mpfr_set_d(&mut mpfr.mpfr, x as c_double, mpfr_rnd_t::MPFR_RNDN);
470            mpfr
471        }
472    }
473}
474
475impl From<Mpz> for Mpfr {
476    fn from(x: Mpz) -> Mpfr {
477        unsafe {
478            let mut mpfr = Mpfr::new();
479            mpfr_set_z(&mut mpfr.mpfr, x.inner(), mpfr_rnd_t::MPFR_RNDN);
480            mpfr
481        }
482    }
483}
484
485impl From<Mpq> for Mpfr {
486    fn from(x: Mpq) -> Mpfr {
487        unsafe {
488            let mut mpfr = Mpfr::new();
489            mpfr_set_q(&mut mpfr.mpfr, x.inner(), mpfr_rnd_t::MPFR_RNDN);
490            mpfr
491        }
492    }
493}
494
495impl From<Mpf> for Mpfr {
496    fn from(x: Mpf) -> Mpfr {
497        unsafe {
498            let mut mpfr = Mpfr::new();
499            mpfr_set_f(&mut mpfr.mpfr, x.inner(), mpfr_rnd_t::MPFR_RNDN);
500            mpfr
501        }
502    }
503}
504
505impl<'a> Into<i64> for &'a Mpfr {
506    fn into(self) -> i64 {
507        unsafe { mpfr_get_si(&self.mpfr, mpfr_rnd_t::MPFR_RNDN) as i64 }
508    }
509}
510
511impl<'a> Into<u64> for &'a Mpfr {
512    fn into(self) -> u64 {
513        unsafe { mpfr_get_ui(&self.mpfr, mpfr_rnd_t::MPFR_RNDN) as u64 }
514    }
515}
516
517impl<'a> Into<f64> for &'a Mpfr {
518    fn into(self) -> f64 {
519        unsafe { mpfr_get_d(&self.mpfr, mpfr_rnd_t::MPFR_RNDN) as f64 }
520    }
521}
522
523impl<'a> Into<Mpz> for &'a Mpfr {
524    fn into(self) -> Mpz {
525        unsafe {
526            let mut result = Mpz::new();
527            mpfr_get_z(result.inner_mut(), &self.mpfr, mpfr_rnd_t::MPFR_RNDN);
528            result
529        }
530    }
531}
532
533impl<'a> Into<Mpf> for &'a Mpfr {
534    fn into(self) -> Mpf {
535        unsafe {
536            let mut result = Mpf::new(self.get_prec());
537            mpfr_get_f(result.inner_mut(), &self.mpfr, mpfr_rnd_t::MPFR_RNDN);
538            result
539        }
540    }
541}
542
543//
544// Addition
545//
546// Supports:
547// Mpfr + Mpfr
548// Mpfr + f64, f64 + Mpfr
549// Mpfr + i64, i64 + Mpfr
550//
551//
552
553impl<'a, 'b> Add<&'a Mpfr> for &'b Mpfr {
554    type Output = Mpfr;
555    fn add(self, other: &Mpfr) -> Mpfr {
556        unsafe {
557            let mut res = Mpfr::new2(cmp::max(self.get_prec(), other.get_prec()));
558            mpfr_add(&mut res.mpfr,
559                     &self.mpfr,
560                     &other.mpfr,
561                     mpfr_rnd_t::MPFR_RNDN);
562            res
563        }
564    }
565}
566
567impl<'a> Add<&'a Mpfr> for Mpfr {
568    type Output = Mpfr;
569    #[inline]
570    fn add(mut self, other: &Mpfr) -> Mpfr {
571        if other.get_prec() > self.get_prec() {
572            return &self + other;
573        }
574        unsafe {
575            mpfr_add(&mut self.mpfr,
576                     &self.mpfr,
577                     &other.mpfr,
578                     mpfr_rnd_t::MPFR_RNDN);
579            self
580        }
581    }
582}
583
584impl Add<Mpfr> for f64 {
585	type Output = Mpfr;
586    fn add(self, other: Mpfr) -> Mpfr {
587        unsafe {
588            let mut res = Mpfr::new2(other.get_prec());
589            mpfr_add_d(&mut res.mpfr,
590                       &other.mpfr,
591                       self as c_double,
592                       mpfr_rnd_t::MPFR_RNDN);
593            res
594        }
595    }
596}
597
598impl<'a> Add<&'a Mpfr> for f64 {
599	type Output = Mpfr;
600    fn add(self, other: &'a Mpfr) -> Mpfr {
601        unsafe {
602            let mut res = Mpfr::new2(other.get_prec());
603            mpfr_add_d(&mut res.mpfr,
604                       &other.mpfr,
605                       self as c_double,
606                       mpfr_rnd_t::MPFR_RNDN);
607            res
608        }
609    }
610}
611
612impl Add<f64> for Mpfr {
613	type Output = Mpfr;
614    #[inline]
615    fn add(mut self, other: f64) -> Mpfr {
616        unsafe {
617            mpfr_add_d(&mut self.mpfr,
618                       &self.mpfr,
619                       other as c_double,
620                       mpfr_rnd_t::MPFR_RNDN);
621            self
622        }
623    }
624}
625
626impl<'a> Add<f64> for &'a Mpfr {
627	type Output = Mpfr;
628    fn add(self, other: f64) -> Mpfr {
629        unsafe {
630            let mut res = Mpfr::new2(self.get_prec());
631            mpfr_add_d(&mut res.mpfr,
632                       &self.mpfr,
633                       other as c_double,
634                       mpfr_rnd_t::MPFR_RNDN);
635            res
636        }
637    }
638}
639
640impl Add<Mpfr> for i64 {
641	type Output = Mpfr;
642    fn add(self, other: Mpfr) -> Mpfr {
643        unsafe {
644            let mut res = Mpfr::new2(other.get_prec());
645            mpfr_add_si(&mut res.mpfr,
646                        &other.mpfr,
647                        self as c_long,
648                        mpfr_rnd_t::MPFR_RNDN);
649            res
650        }
651    }
652}
653
654impl<'a> Add<&'a Mpfr> for i64 {
655	type Output = Mpfr;
656    fn add(self, other: &'a Mpfr) -> Mpfr {
657        unsafe {
658            let mut res = Mpfr::new2(other.get_prec());
659            mpfr_add_si(&mut res.mpfr,
660                        &other.mpfr,
661                        self as c_long,
662                        mpfr_rnd_t::MPFR_RNDN);
663            res
664        }
665    }
666}
667
668impl Add<i64> for Mpfr {
669	type Output = Mpfr;
670    #[inline]
671    fn add(mut self, other: i64) -> Mpfr {
672        unsafe {
673            mpfr_add_si(&mut self.mpfr,
674                        &self.mpfr,
675                        other as c_long,
676                        mpfr_rnd_t::MPFR_RNDN);
677            self
678        }
679    }
680}
681
682impl<'a> Add<i64> for &'a Mpfr {
683	type Output = Mpfr;
684    fn add(self, other: i64) -> Mpfr {
685        unsafe {
686            let mut res = Mpfr::new2(self.get_prec());
687            mpfr_add_si(&mut res.mpfr,
688                        &self.mpfr,
689                        other as c_long,
690                        mpfr_rnd_t::MPFR_RNDN);
691            res
692        }
693    }
694}
695
696//
697// Subtraction
698//
699// Supports:
700// Mpfr - Mpfr
701// Mpfr - f64, f64 - Mpfr
702// Mpfr - i64, i64 - Mpfr
703//
704//
705
706impl<'a, 'b> Sub<&'a Mpfr> for &'b Mpfr {
707    type Output = Mpfr;
708    fn sub(self, other: &Mpfr) -> Mpfr {
709        unsafe {
710            let mut res = Mpfr::new2(cmp::max(self.get_prec(), other.get_prec()));
711            mpfr_sub(&mut res.mpfr,
712                     &self.mpfr,
713                     &other.mpfr,
714                     mpfr_rnd_t::MPFR_RNDN);
715            res
716        }
717    }
718}
719
720impl<'a> Sub<&'a Mpfr> for Mpfr {
721    type Output = Mpfr;
722    #[inline]
723    fn sub(mut self, other: &Mpfr) -> Mpfr {
724        if other.get_prec() > self.get_prec() {
725            return &self - other;
726        }
727        unsafe {
728            mpfr_sub(&mut self.mpfr,
729                     &self.mpfr,
730                     &other.mpfr,
731                     mpfr_rnd_t::MPFR_RNDN);
732            self
733        }
734    }
735}
736
737impl Sub<Mpfr> for f64 {
738	type Output = Mpfr;
739    fn sub(self, other: Mpfr) -> Mpfr {
740        unsafe {
741            let mut res = Mpfr::new2(other.get_prec());
742            mpfr_d_sub(&mut res.mpfr,
743                       self as c_double,
744                       &other.mpfr,
745                       mpfr_rnd_t::MPFR_RNDN);
746            res
747        }
748    }
749}
750
751impl<'a> Sub<&'a Mpfr> for f64 {
752	type Output = Mpfr;
753    fn sub(self, other: &'a Mpfr) -> Mpfr {
754        unsafe {
755            let mut res = Mpfr::new2(other.get_prec());
756            mpfr_d_sub(&mut res.mpfr,
757                       self as c_double,
758                       &other.mpfr,
759                       mpfr_rnd_t::MPFR_RNDN);
760            res
761        }
762    }
763}
764
765impl Sub<f64> for Mpfr {
766	type Output = Mpfr;
767    #[inline]
768    fn sub(mut self, other: f64) -> Mpfr {
769        unsafe {
770            mpfr_sub_d(&mut self.mpfr,
771                       &self.mpfr,
772                       other as c_double,
773                       mpfr_rnd_t::MPFR_RNDN);
774            self
775        }
776    }
777}
778
779impl<'a> Sub<f64> for &'a Mpfr {
780	type Output = Mpfr;
781    fn sub(self, other: f64) -> Mpfr {
782        unsafe {
783            let mut res = Mpfr::new2(self.get_prec());
784            mpfr_sub_d(&mut res.mpfr,
785                       &self.mpfr,
786                       other as c_double,
787                       mpfr_rnd_t::MPFR_RNDN);
788            res
789        }
790    }
791}
792
793impl Sub<Mpfr> for i64 {
794	type Output = Mpfr;
795    fn sub(self, other: Mpfr) -> Mpfr {
796        unsafe {
797            let mut res = Mpfr::new2(other.get_prec());
798            mpfr_si_sub(&mut res.mpfr,
799                        self as c_long,
800                        &other.mpfr,
801                        mpfr_rnd_t::MPFR_RNDN);
802            res
803        }
804    }
805}
806
807impl<'a> Sub<&'a Mpfr> for i64 {
808	type Output = Mpfr;
809    fn sub(self, other: &'a Mpfr) -> Mpfr {
810        unsafe {
811            let mut res = Mpfr::new2(other.get_prec());
812            mpfr_si_sub(&mut res.mpfr,
813                        self as c_long,
814                        &other.mpfr,
815                        mpfr_rnd_t::MPFR_RNDN);
816            res
817        }
818    }
819}
820
821impl Sub<i64> for Mpfr {
822	type Output = Mpfr;
823    #[inline]
824    fn sub(mut self, other: i64) -> Mpfr {
825        unsafe {
826            mpfr_sub_si(&mut self.mpfr,
827                        &self.mpfr,
828                        other as c_long,
829                        mpfr_rnd_t::MPFR_RNDN);
830            self
831        }
832    }
833}
834
835impl<'a> Sub<i64> for &'a Mpfr {
836	type Output = Mpfr;
837    fn sub(self, other: i64) -> Mpfr {
838        unsafe {
839            let mut res = Mpfr::new2(self.get_prec());
840            mpfr_sub_si(&mut res.mpfr,
841                        &self.mpfr,
842                        other as c_long,
843                        mpfr_rnd_t::MPFR_RNDN);
844            res
845        }
846    }
847}
848
849//
850// Multiplication
851//
852// Supports:
853// Mpfr * Mpfr
854// Mpfr * f64, f64 * Mpfr
855// Mpfr * i64, i64 * Mpfr
856//
857//
858
859impl<'a, 'b> Mul<&'a Mpfr> for &'b Mpfr {
860    type Output = Mpfr;
861    fn mul(self, other: &Mpfr) -> Mpfr {
862        unsafe {
863            let mut res = Mpfr::new2(cmp::max(self.get_prec(), other.get_prec()));
864            mpfr_mul(&mut res.mpfr,
865                     &self.mpfr,
866                     &other.mpfr,
867                     mpfr_rnd_t::MPFR_RNDN);
868            res
869        }
870    }
871}
872
873impl<'a> Mul<&'a Mpfr> for Mpfr {
874    type Output = Mpfr;
875
876    #[inline]
877    fn mul(mut self, other: &Mpfr) -> Mpfr {
878        if other.get_prec() > self.get_prec() {
879            return &self * other;
880        }
881        unsafe {
882            mpfr_mul(&mut self.mpfr,
883                     &self.mpfr,
884                     &other.mpfr,
885                     mpfr_rnd_t::MPFR_RNDN);
886            self
887        }
888    }
889}
890
891impl Mul<Mpfr> for f64 {
892	type Output = Mpfr;
893    fn mul(self, other: Mpfr) -> Mpfr {
894        unsafe {
895            let mut res = Mpfr::new2(other.get_prec());
896            mpfr_mul_d(&mut res.mpfr,
897                       &other.mpfr,
898                       self as c_double,
899                       mpfr_rnd_t::MPFR_RNDN);
900            res
901        }
902    }
903}
904
905impl<'a> Mul<&'a Mpfr> for f64 {
906	type Output = Mpfr;
907    fn mul(self, other: &'a Mpfr) -> Mpfr {
908        unsafe {
909            let mut res = Mpfr::new2(other.get_prec());
910            mpfr_mul_d(&mut res.mpfr,
911                       &other.mpfr,
912                       self as c_double,
913                       mpfr_rnd_t::MPFR_RNDN);
914            res
915        }
916    }
917}
918
919impl Mul<f64> for Mpfr {
920	type Output = Mpfr;
921    #[inline]
922    fn mul(mut self, other: f64) -> Mpfr {
923        unsafe {
924            mpfr_mul_d(&mut self.mpfr,
925                       &self.mpfr,
926                       other as c_double,
927                       mpfr_rnd_t::MPFR_RNDN);
928            self
929        }
930    }
931}
932
933impl<'a> Mul<f64> for &'a Mpfr {
934	type Output = Mpfr;
935    fn mul(self, other: f64) -> Mpfr {
936        unsafe {
937            let mut res = Mpfr::new2(self.get_prec());
938            mpfr_mul_d(&mut res.mpfr,
939                       &self.mpfr,
940                       other as c_double,
941                       mpfr_rnd_t::MPFR_RNDN);
942            res
943        }
944    }
945}
946
947impl Mul<Mpfr> for i64 {
948	type Output = Mpfr;
949    fn mul(self, other: Mpfr) -> Mpfr {
950        unsafe {
951            let mut res = Mpfr::new2(other.get_prec());
952            mpfr_mul_si(&mut res.mpfr,
953                        &other.mpfr,
954                        self as c_long,
955                        mpfr_rnd_t::MPFR_RNDN);
956            res
957        }
958    }
959}
960
961impl<'a> Mul<&'a Mpfr> for i64 {
962	type Output = Mpfr;
963    fn mul(self, other: &'a Mpfr) -> Mpfr {
964        unsafe {
965            let mut res = Mpfr::new2(other.get_prec());
966            mpfr_mul_si(&mut res.mpfr,
967                        &other.mpfr,
968                        self as c_long,
969                        mpfr_rnd_t::MPFR_RNDN);
970            res
971        }
972    }
973}
974
975impl Mul<i64> for Mpfr {
976	type Output = Mpfr;
977    #[inline]
978    fn mul(mut self, other: i64) -> Mpfr {
979        unsafe {
980            mpfr_mul_si(&mut self.mpfr,
981                        &self.mpfr,
982                        other as c_long,
983                        mpfr_rnd_t::MPFR_RNDN);
984            self
985        }
986    }
987}
988
989impl<'a> Mul<i64> for &'a Mpfr {
990	type Output = Mpfr;
991    fn mul(self, other: i64) -> Mpfr {
992        unsafe {
993            let mut res = Mpfr::new2(self.get_prec());
994            mpfr_mul_si(&mut res.mpfr,
995                        &self.mpfr,
996                        other as c_long,
997                        mpfr_rnd_t::MPFR_RNDN);
998            res
999        }
1000    }
1001}
1002
1003//
1004// Division
1005//
1006// Supports:
1007// Mpfr / Mpfr
1008// Mpfr / f64, f64 / Mpfr
1009// Mpfr / i64, i64 / Mpfr
1010//
1011//
1012
1013impl<'a, 'b> Div<&'a Mpfr> for &'b Mpfr {
1014    type Output = Mpfr;
1015    fn div(self, other: &Mpfr) -> Mpfr {
1016        unsafe {
1017            if mpfr_cmp_ui(&other.mpfr, 0) == 0 {
1018                panic!("divide by zero")
1019            }
1020
1021            let mut res = Mpfr::new2(cmp::max(self.get_prec(), other.get_prec()));
1022            mpfr_div(&mut res.mpfr,
1023                     &self.mpfr,
1024                     &other.mpfr,
1025                     mpfr_rnd_t::MPFR_RNDN);
1026            res
1027        }
1028    }
1029}
1030
1031impl<'a> Div<&'a Mpfr> for Mpfr {
1032    type Output = Mpfr;
1033    #[inline]
1034    fn div(mut self, other: &Mpfr) -> Mpfr {
1035        if other.get_prec() > self.get_prec() {
1036            return &self / other;
1037        }
1038        unsafe {
1039            if mpfr_cmp_ui(&other.mpfr, 0) == 0 {
1040                panic!("divide by zero")
1041            }
1042            mpfr_div(&mut self.mpfr,
1043                     &self.mpfr,
1044                     &other.mpfr,
1045                     mpfr_rnd_t::MPFR_RNDN);
1046            self
1047        }
1048    }
1049}
1050
1051impl Div<Mpfr> for f64 {
1052	type Output = Mpfr;
1053    fn div(self, other: Mpfr) -> Mpfr {
1054        unsafe {
1055            if mpfr_cmp_ui(&other.mpfr, 0) == 0 {
1056                panic!("divide by zero")
1057            }
1058
1059            let mut res = Mpfr::new2(other.get_prec());
1060            mpfr_d_div(&mut res.mpfr,
1061                       self as c_double,
1062                       &other.mpfr,
1063                       mpfr_rnd_t::MPFR_RNDN);
1064            res
1065        }
1066    }
1067}
1068
1069impl<'a> Div<&'a Mpfr> for f64 {
1070	type Output = Mpfr;
1071    fn div(self, other: &'a Mpfr) -> Mpfr {
1072        unsafe {
1073            if mpfr_cmp_ui(&other.mpfr, 0) == 0 {
1074                panic!("divide by zero")
1075            }
1076
1077            let mut res = Mpfr::new2(other.get_prec());
1078            mpfr_d_div(&mut res.mpfr,
1079                       self as c_double,
1080                       &other.mpfr,
1081                       mpfr_rnd_t::MPFR_RNDN);
1082            res
1083        }
1084    }
1085}
1086
1087impl Div<f64> for Mpfr {
1088	type Output = Mpfr;
1089    #[inline]
1090    fn div(mut self, other: f64) -> Mpfr {
1091        unsafe {
1092            if other == 0.0 {
1093                panic!("divide by zero")
1094            }
1095
1096            mpfr_div_d(&mut self.mpfr,
1097                       &self.mpfr,
1098                       other as c_double,
1099                       mpfr_rnd_t::MPFR_RNDN);
1100            self
1101        }
1102    }
1103}
1104
1105impl<'a> Div<f64> for &'a Mpfr {
1106	type Output = Mpfr;
1107    fn div(self, other: f64) -> Mpfr {
1108        unsafe {
1109            if other == 0.0 {
1110                panic!("divide by zero")
1111            }
1112
1113            let mut res = Mpfr::new2(self.get_prec());
1114            mpfr_div_d(&mut res.mpfr,
1115                       &self.mpfr,
1116                       other as c_double,
1117                       mpfr_rnd_t::MPFR_RNDN);
1118            res
1119        }
1120    }
1121}
1122
1123impl Div<Mpfr> for i64 {
1124	type Output = Mpfr;
1125    fn div(self, other: Mpfr) -> Mpfr {
1126        unsafe {
1127            if mpfr_cmp_ui(&other.mpfr, 0) == 0 {
1128                panic!("divide by zero")
1129            }
1130
1131            let mut res = Mpfr::new2(other.get_prec());
1132            mpfr_si_div(&mut res.mpfr,
1133                        self as c_long,
1134                        &other.mpfr,
1135                        mpfr_rnd_t::MPFR_RNDN);
1136            res
1137        }
1138    }
1139}
1140
1141impl<'a> Div<&'a Mpfr> for i64 {
1142	type Output = Mpfr;
1143    fn div(self, other: &'a Mpfr) -> Mpfr {
1144        unsafe {
1145            if mpfr_cmp_ui(&other.mpfr, 0) == 0 {
1146                panic!("divide by zero")
1147            }
1148
1149            let mut res = Mpfr::new2(other.get_prec());
1150            mpfr_si_div(&mut res.mpfr,
1151                        self as c_long,
1152                        &other.mpfr,
1153                        mpfr_rnd_t::MPFR_RNDN);
1154            res
1155        }
1156    }
1157}
1158
1159impl Div<i64> for Mpfr {
1160	type Output = Mpfr;
1161    #[inline]
1162    fn div(mut self, other: i64) -> Mpfr {
1163        unsafe {
1164            if other == 0 {
1165                panic!("divide by zero")
1166            }
1167
1168            mpfr_div_si(&mut self.mpfr,
1169                        &self.mpfr,
1170                        other as c_long,
1171                        mpfr_rnd_t::MPFR_RNDN);
1172            self
1173        }
1174    }
1175}
1176
1177impl<'a> Div<i64> for &'a Mpfr {
1178	type Output = Mpfr;
1179    fn div(self, other: i64) -> Mpfr {
1180        unsafe {
1181            if other == 0 {
1182                panic!("divide by zero")
1183            }
1184
1185            let mut res = Mpfr::new2(self.get_prec());
1186            mpfr_div_si(&mut res.mpfr,
1187                        &self.mpfr,
1188                        other as c_long,
1189                        mpfr_rnd_t::MPFR_RNDN);
1190            res
1191        }
1192    }
1193}
1194
1195// Negation
1196
1197impl<'b> Neg for &'b Mpfr {
1198    type Output = Mpfr;
1199    fn neg(self) -> Mpfr {
1200        unsafe {
1201            let mut res = Mpfr::new2(self.get_prec());
1202            mpfr_neg(&mut res.mpfr, &self.mpfr, mpfr_rnd_t::MPFR_RNDN);
1203            res
1204        }
1205    }
1206}
1207
1208impl Neg for Mpfr {
1209    type Output = Mpfr;
1210    #[inline]
1211    fn neg(mut self) -> Mpfr {
1212        unsafe {
1213            mpfr_neg(&mut self.mpfr, &self.mpfr, mpfr_rnd_t::MPFR_RNDN);
1214            self
1215        }
1216    }
1217}
1218
1219gen_overloads!(Mpfr);
1220
1221// rustc_serialize support
1222impl Decodable for Mpfr {
1223    fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
1224        let s = try!(d.read_str());
1225        match Mpfr::new_from_str(s, 10) {
1226            Some(val) => Ok(val),
1227            None => Err(d.error("Cannot parse decimal float")),
1228        }
1229    }
1230}
1231
1232impl Encodable for Mpfr {
1233    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
1234        s.emit_str(&self.to_string())
1235    }
1236}