rcalc_lib/
value.rs

1use dtoa;
2use num_bigint::{BigInt, Sign};
3use num_complex::Complex;
4use num_rational::BigRational;
5use num_traits::{FromPrimitive, Num, One, ToPrimitive, Zero};
6use std::f64::{consts, EPSILON};
7use std::fmt;
8use std::str;
9
10use crate::errors::*;
11
12/// Expression calculation result: either value or error
13pub type CalcResult = Result<Value, CalcError>;
14pub(crate) type CalcErrorResult = Result<(), CalcError>;
15
16/// Supported value types (Float is used for angles in degrees)
17#[derive(Clone)]
18pub enum Value {
19    /// Big integer number
20    Int(BigInt),
21    /// Float number
22    Float(f64),
23    /// Rational number (numerator and denominator are big integers)
24    Ratio(BigRational),
25    /// Complex number
26    Complex(Complex<f64>),
27}
28
29const F64_BUF_LEN: usize = 48;
30fn format_f64(g: f64) -> String {
31    let mut buf = [b'\0'; F64_BUF_LEN];
32    match dtoa::write(&mut buf[..], g) {
33        Ok(len) => match str::from_utf8(&buf[..len]) {
34            Ok(s) => s.to_string(),
35            Err(..) => format!("{}", g),
36        },
37        Err(..) => format!("{}", g),
38    }
39}
40
41pub(crate) fn f64_equal(f1: f64, f2: f64) -> bool {
42    (f1 - f2).abs() <= EPSILON
43}
44
45impl fmt::Display for Value {
46    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
47        match &self {
48            Value::Int(ref i) => write!(f, "{}", i),
49            Value::Float(ref g) => write!(f, "{}", format_f64(*g)),
50            Value::Ratio(ref r) => {
51                let i = r.clone().to_integer();
52                if i.is_zero() {
53                    write!(f, "{}\\{}", r.numer(), r.denom())
54                } else {
55                    let mut rc = r.fract();
56                    if rc < BigRational::zero() {
57                        rc = -rc;
58                    }
59                    write!(f, "{}\\{}\\{}", i, rc.numer(), rc.denom())
60                }
61            }
62            Value::Complex(ref c) => {
63                if c.im >= 0.0 {
64                    write!(f, "{}+{}i", format_f64(c.re), format_f64(c.im))
65                } else {
66                    write!(f, "{}{}i", format_f64(c.re), format_f64(c.im))
67                }
68            }
69        }
70    }
71}
72
73impl fmt::Debug for Value {
74    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75        match &self {
76            Value::Int(ref i) => write!(f, " Int({:?})", i),
77            Value::Float(ref g) => write!(f, " Float({:?})", g),
78            Value::Ratio(ref r) => write!(f, " Ratio({:?})", r),
79            Value::Complex(ref c) => write!(f, " Complex({:?})", c),
80        }
81    }
82}
83
84impl PartialEq for Value {
85    fn eq(&self, other: &Value) -> bool {
86        match (self, &other) {
87            (Value::Int(ref i1), Value::Int(ref i2)) => i1 == i2,
88            (Value::Float(ref f1), Value::Float(ref f2)) => f1 == f2,
89            (Value::Ratio(ref r1), Value::Ratio(ref r2)) => r1 == r2,
90            (Value::Complex(ref c1), Value::Complex(ref c2)) => c1 == c2,
91            (_, _) => false,
92        }
93    }
94}
95
96fn int_to_f64(i: &BigInt) -> Result<f64, CalcError> {
97    if let Some(f) = i.to_f64() {
98        Ok(f)
99    } else {
100        Err(CalcError::IntToFloat(i.clone()))
101    }
102}
103
104fn f64_to_int(f: f64) -> Result<BigInt, CalcError> {
105    if let Some(i) = BigInt::from_f64(f) {
106        Ok(i)
107    } else {
108        Err(CalcError::FloatToInt(f))
109    }
110}
111
112fn f64_to_ratio(f: f64) -> Result<BigRational, CalcError> {
113    if let Some(r) = BigRational::from_float(f) {
114        Ok(r)
115    } else {
116        Err(CalcError::FloatToRatio(f))
117    }
118}
119
120fn ratio_to_f64(r: &BigRational) -> Result<f64, CalcError> {
121    if r.is_zero() {
122        return Ok(0.0);
123    }
124    // extract the integer part first to avoid float overflow
125    // in case of very long numer and denom
126    let i = if let Some(f) = r.clone().to_integer().to_f64() {
127        f
128    } else {
129        return Err(CalcError::RatioToFloat(r.clone()));
130    };
131    let r = r.fract();
132    let n = if let Some(f) = r.numer().to_f64() {
133        f
134    } else {
135        return Err(CalcError::RatioToFloat(r.clone()));
136    };
137    let d = if let Some(f) = r.denom().to_f64() {
138        f
139    } else {
140        return Err(CalcError::RatioToFloat(r.clone()));
141    };
142    Ok(i + n / d)
143}
144
145fn str_to_bigint(s: &str) -> Result<BigInt, CalcError> {
146    let s = s.replace("_", "");
147    let s = s.replace(" ", "");
148    let plen = "0x".len();
149    if s.starts_with("0x") || s.starts_with("0X") {
150        if let Ok(bi) = BigInt::from_str_radix(&s[plen..], 16) {
151            return Ok(bi);
152        }
153        return Err(CalcError::StrToInt(s));
154    } else if s.starts_with("0o") || s.starts_with("0O") {
155        if let Ok(bi) = BigInt::from_str_radix(&s[plen..], 8) {
156            return Ok(bi);
157        }
158        return Err(CalcError::StrToInt(s));
159    } else if s.starts_with("0b") || s.starts_with("0B") {
160        if let Ok(bi) = BigInt::from_str_radix(&s[plen..], 2) {
161            return Ok(bi);
162        }
163        return Err(CalcError::StrToInt(s));
164    }
165
166    let pos = s.find(|c: char| c == 'e' || c == 'E').unwrap_or(0);
167    if pos == 0 {
168        if let Ok(i) = s.parse() {
169            return Ok(i);
170        } else {
171            return Err(CalcError::StrToInt(s.to_owned()));
172        }
173    }
174    let (s1, s2) = s.split_at(pos);
175    let s2 = s2.trim_start_matches(|c| c == 'E' || c == 'e' || c == '+');
176
177    let base = s1.parse();
178    let pow = s2.parse();
179    if base.is_err() || pow.is_err() {
180        return Err(CalcError::StrToInt(s.to_owned()));
181    }
182
183    let mut base = base.unwrap();
184    let pow = pow.unwrap();
185    // TODO: fast power 10
186    for _i in 0..pow {
187        base *= 10;
188    }
189    Ok(base)
190}
191
192fn str_to_f64(s: &str) -> Result<f64, CalcError> {
193    if let Ok(f) = s.parse::<f64>() {
194        Ok(f)
195    } else {
196        Err(CalcError::StrToFloat(s.to_owned()))
197    }
198}
199
200macro_rules! basic_op {
201    ($id:ident, $op:tt, $cond:ident) => {
202        pub fn $id(self, rhs: Value) -> CalcResult {
203            match (&self, &rhs) {
204                (Value::Complex(..), ..) | (.., Value::Complex(..)) => {
205                    let c1 = self.into_raw_complex()?;
206                    let c2 = rhs.into_raw_complex()?;
207                    let c = Value::Complex(c1 $op c2);
208                    if Value::is_like_int(&c) {
209                        return Value::into_int(c);
210                    }
211                    Ok(c)
212                },
213                (Value::Float(..), ..) | (.., Value::Float(..)) => {
214                    let f1 = self.into_raw_f64()?;
215                    let f2 = rhs.into_raw_f64()?;
216                    let f = Value::Float(f1 $op f2);
217                    if Value::is_like_int(&f) {
218                        return Value::into_int(f);
219                    }
220                    Ok(f)
221                },
222                (Value::Ratio(..), ..) | (.., Value::Ratio(..)) => {
223                    let r1 = self.into_raw_ratio()?;
224                    let r2 = rhs.into_raw_ratio()?;
225                    let r = Value::Ratio(r1 $op r2);
226                    if Value::is_like_int(&r) {
227                        return Value::into_int(r);
228                    }
229                    Ok(r)
230                },
231                _ => {
232                    let i1 = self.into_raw_big_int()?;
233                    let i2 = rhs.into_raw_big_int()?;
234                    if $cond {
235                        if i1.clone() % i2.clone() == BigInt::zero() {
236                            return Ok(Value::Int(i1 $op i2))
237                        }
238                        let f1 = i1.to_f64();
239                        let f2 = i2.to_f64();
240                        match (f1, f2) {
241                            (Some(ff1), Some(ff2)) => {
242                                Ok(Value::Float(ff1 / ff2))
243                            },
244                            (_, _) => {
245                                Ok(Value::Int(i1 $op i2))
246                            },
247                        }
248                    } else {
249                        Ok(Value::Int(i1 $op i2))
250                    }
251                },
252            }
253        }
254    }
255}
256
257macro_rules! div_op {
258    ($id:ident, $op:tt, $cond:ident) => {
259        pub fn $id(self, rhs: Value) -> CalcResult {
260            if rhs.is_zero() {
261                return Err(CalcError::DividedByZero(format!("{}", self)));
262            }
263            match (&self, &rhs) {
264                (Value::Complex(..), ..) | (.., Value::Complex(..)) => {
265                    let c2 = rhs.into_raw_complex()?;
266                    let c1 = self.into_raw_complex()?;
267                    let c = Value::Complex(c1 $op c2);
268                    if Value::is_like_int(&c) {
269                        return Value::into_int(c);
270                    }
271                    Ok(c)
272                },
273                (Value::Float(..), ..) | (.., Value::Float(..)) => {
274                    let f2 = rhs.into_raw_f64()?;
275                    let f1 = self.into_raw_f64()?;
276                    let f = Value::Float(f1 $op f2);
277                    if Value::is_like_int(&f) {
278                        return Value::into_int(f);
279                    }
280                    Ok(f)
281                },
282                (Value::Ratio(..), ..) | (.., Value::Ratio(..)) => {
283                    let r2 = rhs.into_raw_ratio()?;
284                    let r1 = self.into_raw_ratio()?;
285                    let r = Value::Ratio(r1 $op r2);
286                    if Value::is_like_int(&r) {
287                        return Value::into_int(r);
288                    }
289                    Ok(r)
290                },
291                _ => {
292                    let i2 = rhs.into_raw_big_int()?;
293                    let i1 = self.into_raw_big_int()?;
294                    if $cond {
295                        if i1.clone() % i2.clone() == BigInt::zero() {
296                            return Ok(Value::Int(i1 $op i2))
297                        }
298                        let f1 = i1.to_f64();
299                        let f2 = i2.to_f64();
300                        match (f1, f2) {
301                            (Some(ff1), Some(ff2)) => {
302                                Ok(Value::Float(ff1 / ff2))
303                            },
304                            (_, _) => {
305                                Ok(Value::Int(i1 $op i2))
306                            },
307                        }
308                    } else {
309                        Ok(Value::Int(i1 $op i2))
310                    }
311                },
312            }
313        }
314    }
315}
316
317macro_rules! cmp_op {
318    ($id:ident, $op:tt) => {
319        pub fn $id(self, rhs: Value) -> CalcResult {
320            match (&self, &rhs) {
321                (Value::Complex(..), ..) | (.., Value::Complex(..)) => {
322                    let c1 = self.into_raw_complex()?;
323                    let c2 = rhs.into_raw_complex()?;
324                    if c1.re $op c2.re && c1.im $op c2.im {
325                        Ok(Value::Int(BigInt::one()))
326                    } else {
327                        Ok(Value::Int(BigInt::zero()))
328                    }
329                },
330                (Value::Float(..), ..) | (.., Value::Float(..)) => {
331                    let f1 = self.into_raw_f64()?;
332                    let f2 = rhs.into_raw_f64()?;
333                    if f1 $op f2 {
334                        Ok(Value::Int(BigInt::one()))
335                    } else {
336                        Ok(Value::Int(BigInt::zero()))
337                    }
338                },
339                (Value::Ratio(..), ..) | (.., Value::Ratio(..)) => {
340                    let r1 = self.into_raw_ratio()?;
341                    let r2 = rhs.into_raw_ratio()?;
342                    if r1 $op r2 {
343                        Ok(Value::Int(BigInt::one()))
344                    } else {
345                        Ok(Value::Int(BigInt::zero()))
346                    }
347                },
348                _ => {
349                    let i1 = self.into_raw_big_int()?;
350                    let i2 = rhs.into_raw_big_int()?;
351                    if i1 $op i2 {
352                        Ok(Value::Int(BigInt::one()))
353                    } else {
354                        Ok(Value::Int(BigInt::zero()))
355                    }
356                },
357            }
358        }
359    }
360}
361macro_rules! cmp_op_inv {
362    ($id:ident, $idcall: ident, $op:tt) => {
363        pub fn $id(self, rhs: Value) -> CalcResult {
364            let res = self.$idcall(rhs)?;
365            if res.is_zero() {
366                Ok(Value::Int(BigInt::one()))
367            } else {
368                Ok(Value::Int(BigInt::zero()))
369            }
370        }
371    };
372}
373
374macro_rules! round_op {
375    ($id:ident) => {
376        pub fn $id(self) -> CalcResult {
377            match &self {
378                Value::Complex(c) => {
379                    let v = Value::Complex(Complex::new(c.re.$id(), c.im.$id()));
380                    if Value::is_like_int(&v) {
381                        let v = Value::into_int(v)?;
382                        Ok(v)
383                    } else {
384                        Ok(v)
385                    }
386                }
387                Value::Ratio(r) => {
388                    let v = Value::Ratio(r.$id());
389                    if Value::is_like_int(&v) {
390                        let v = Value::into_int(v)?;
391                        Ok(v)
392                    } else {
393                        Ok(v)
394                    }
395                }
396                Value::Float(f) => {
397                    let v = Value::Float(f.$id());
398                    let v = Value::into_int(v)?;
399                    Ok(v)
400                }
401                Value::Int(i) => Ok(Value::Int(i.clone())),
402            }
403        }
404    };
405}
406
407macro_rules! bitwise_op {
408    ($id:ident, $op:tt) => {
409        pub fn $id(self, rhs: Value) -> CalcResult {
410            match (&self, &rhs) {
411                (Value::Int(i1), Value::Int(i2)) => {
412                    let i1 = i1 $op i2;
413                    Ok(Value::Int(i1))
414                },
415                _ => Err(CalcError::OnlyInt("bitwise operator".to_string())),
416            }
417        }
418    }
419}
420macro_rules! bitwise_shift_op {
421    ($id:ident, $op:tt) => {
422        pub fn $id(self, rhs: Value) -> CalcResult {
423            match (&self, &rhs) {
424                (Value::Int(i1), Value::Int(i2)) => {
425                    let shift = if let Some(us) = i2.clone().to_usize() {
426                        us
427                    } else {
428                        return Err(CalcError::InvalidShift(format!("{}", i2)))
429                    };
430                    let i1 = i1 $op shift;
431                    Ok(Value::Int(i1))
432                },
433                _ => Err(CalcError::OnlyInt("bitwise operator".to_string())),
434            }
435        }
436    }
437}
438
439macro_rules! sin_cos {
440    ($id:ident) => {
441        pub fn $id(self) -> CalcResult {
442            match &self {
443                Value::Complex(c) => Ok(Value::Complex(c.$id())),
444                Value::Float(f) => Ok(Value::Float(f.$id())),
445                _ => {
446                    let f = self.into_raw_f64()?;
447                    Ok(Value::Float(f.$id()))
448                }
449            }
450        }
451    };
452}
453macro_rules! asin_cos {
454    ($id:ident) => {
455        pub fn $id(self) -> CalcResult {
456            match &self {
457                Value::Complex(c) => Ok(Value::Complex(c.$id())),
458                _ => {
459                    let f = self.into_raw_f64()?;
460                    if (-1.0..=1.0).contains(&f) {
461                        Ok(Value::Float(f.$id()))
462                    } else {
463                        let cm = Complex::new(f, 0.0);
464                        Ok(Value::Complex(cm.$id()))
465                    }
466                }
467            }
468        }
469    };
470}
471
472macro_rules! fn_hyper {
473    ($id:ident) => {
474        pub fn $id(self) -> CalcResult {
475            match &self {
476                Value::Complex(c) => Ok(Value::Complex(c.$id())),
477                _ => {
478                    let f = self.clone().into_raw_f64()?;
479                    Ok(Value::Float(f.$id()))
480                }
481            }
482        }
483    };
484}
485
486impl Default for Value {
487    fn default() -> Value {
488        Value::Int(BigInt::zero())
489    }
490}
491
492impl Value {
493    pub fn new() -> Self {
494        Default::default()
495    }
496
497    // --------------------------------
498
499    pub(crate) fn into_int(self) -> CalcResult {
500        match self {
501            Value::Int(..) => Ok(self),
502            Value::Float(f) => {
503                let i = f64_to_int(f.floor())?;
504                Ok(Value::Int(i))
505            }
506            Value::Ratio(r) => Ok(Value::Int(r.to_integer())),
507            Value::Complex(c) => {
508                let i = f64_to_int(c.re.floor())?;
509                Ok(Value::Int(i))
510            }
511        }
512    }
513
514    pub(crate) fn into_float(self) -> CalcResult {
515        match self {
516            Value::Int(i) => {
517                let f = int_to_f64(&i)?;
518                Ok(Value::Float(f))
519            }
520            Value::Float(..) => Ok(self),
521            Value::Ratio(r) => {
522                let f = ratio_to_f64(&r)?;
523                Ok(Value::Float(f))
524            }
525            Value::Complex(c) => Ok(Value::Float(c.re)),
526        }
527    }
528
529    pub(crate) fn into_ratio(self) -> CalcResult {
530        match self {
531            Value::Ratio(..) => Ok(self),
532            Value::Int(i) => Ok(Value::Ratio(BigRational::from_integer(i))),
533            Value::Float(f) => {
534                let r = f64_to_ratio(f)?;
535                Ok(Value::Ratio(r))
536            }
537            Value::Complex(c) => {
538                let r = f64_to_ratio(c.re)?;
539                Ok(Value::Ratio(r))
540            }
541        }
542    }
543
544    pub(crate) fn into_complex(self) -> CalcResult {
545        match self {
546            Value::Complex(..) => Ok(self),
547            Value::Float(f) => Ok(Value::Complex(Complex::new(f, 0.0))),
548            Value::Int(i) => {
549                let f = int_to_f64(&i)?;
550                Ok(Value::Complex(Complex::new(f, 0.0)))
551            }
552            Value::Ratio(r) => {
553                let f = ratio_to_f64(&r)?;
554                Ok(Value::Complex(Complex::new(f, 0.0)))
555            }
556        }
557    }
558
559    //---------------------------------------------
560
561    pub(crate) fn into_raw_f64(self) -> Result<f64, CalcError> {
562        let v = Value::into_float(self)?;
563        match v {
564            Value::Float(f) => Ok(f),
565            _ => Ok(0.0), // unreachable
566        }
567    }
568
569    pub(crate) fn into_raw_big_int(self) -> Result<BigInt, CalcError> {
570        let v = Value::into_int(self)?;
571        match v {
572            Value::Int(i) => Ok(i),
573            _ => Ok(BigInt::zero()), // unreachable
574        }
575    }
576
577    pub(crate) fn into_raw_ratio(self) -> Result<BigRational, CalcError> {
578        let v = Value::into_ratio(self)?;
579        match v {
580            Value::Ratio(r) => Ok(r),
581            _ => Ok(BigRational::zero()), // unreachable
582        }
583    }
584
585    pub(crate) fn into_raw_complex(self) -> Result<Complex<f64>, CalcError> {
586        let v = Value::into_complex(self)?;
587        match v {
588            Value::Complex(c) => Ok(c),
589            _ => Ok(Complex::zero()), // unreachable
590        }
591    }
592
593    //---------------------------------------------
594
595    /// Convert &str to big integer number
596    /// Supported formats:
597    /// * Raw integer number - `1234`
598    /// * Integer number and exponent (it must not include decimal point) - `12e2` = `1200`
599    /// * Hexadecimal number - `0x12` or `0X12`
600    /// * Octal number - `0o12` or `0O12`
601    /// * Binary number - `0b101` or `0B101`
602    ///
603    /// For convenience digits can be separated with underscores:
604    /// `3_00_1` is the same as `3001`
605    pub fn from_str_integer(s: &str) -> CalcResult {
606        let i = str_to_bigint(s)?;
607        Ok(Value::Int(i))
608    }
609
610    /// Convert &str to float number
611    /// Supported formats:
612    /// * Without exponent - `1.023`
613    /// * With exponent - `1.02e-5`
614    ///
615    /// Comma(,) can be used instead of decimal point(.):
616    /// `1.25` is the same as `1,25`
617    ///
618    /// For convenience digits can be separated with underscores:
619    /// `3_005.245_1` is the same as `3005.2451`
620    pub fn from_str_float(s: &str) -> CalcResult {
621        let s = s.replace("_", "");
622        let s = s.replace(" ", "");
623        let s = s.replace(',', ".");
624        let f = str_to_f64(&s)?;
625        Ok(Value::Float(f))
626    }
627
628    /// Convert &str to rational number
629    /// Supported formats:
630    /// * Numerator and denominator only: `1\2` = one half
631    /// * With integer part: `3\1\2` = three and a half
632    ///
633    /// For convenience digits can be separated with underscores:
634    /// `3_005\1_988` is the same as `3005\1988`
635    pub fn from_str_ratio(st: &str) -> CalcResult {
636        let s = st.replace("_", "");
637        let s = s.replace(" ", "");
638        let sp: Vec<&str> = s.splitn(3, '\\').collect();
639
640        if sp.len() == 1 {
641            return Self::from_str_integer(st);
642        }
643
644        let i = if sp.len() > 2 { str_to_bigint(sp[0])? } else { BigInt::zero() };
645        let n = str_to_bigint(sp[sp.len() - 2])?;
646        let d = str_to_bigint(sp[sp.len() - 1])?;
647
648        if d.is_zero() {
649            Ok(Value::Int(BigInt::zero()))
650        } else {
651            let d1 = d.clone();
652            Ok(Value::Ratio(BigRational::new(i * d1 + n, d)))
653        }
654    }
655
656    /// Convert &str that represents angle in degrees to float number
657    /// Supported formats:
658    /// * Full form with letters - `30d20m50s` - 30 degress, 20 angular minutes and 30 angular seconds
659    /// * Full form with special characters - `30°20'50"`
660    /// * Short form - degrees only - `30.25d` or `30.25°`
661    ///
662    /// Characters can be mixed: `30d20'50"`. Letters can be either lowercase or capital ones.
663    ///
664    /// Comma(,) can be used instead of decimal point(.):
665    /// `1.25d` is the same as `1,25d`
666    ///
667    /// For convenience digits can be separated with underscores:
668    /// `3_005.245_1d` is the same as `3005.2451d`
669    pub fn from_str_angle(s: &str) -> CalcResult {
670        let s = s.replace("_", "");
671        let s = s.replace(",", ".");
672        let parts: Vec<&str> = s
673            .split(|c: char| {
674                c == 'd'
675                    || c == 'D'
676                    || c == '°'
677                    || c == 'm'
678                    || c == 'M'
679                    || c == '\''
680                    || c == 's'
681                    || c == 'S'
682                    || c == '"'
683            })
684            .filter(|s| !(*s).is_empty())
685            .collect();
686
687        let deg_ex = s.find(|c: char| c == 'd' || c == 'D' || c == '°').is_some();
688        let min_ex = s.find(|c: char| c == 'm' || c == 'M' || c == '\'').is_some();
689        let sec_ex = s.find(|c: char| c == 's' || c == 'S' || c == '"').is_some();
690        let mut cnt = 0usize;
691        if deg_ex {
692            cnt += 1;
693        }
694        if min_ex {
695            cnt += 1;
696        }
697        if sec_ex {
698            cnt += 1;
699        }
700        if cnt > parts.len() {
701            return Err(CalcError::AngleToFloat(s.to_owned()));
702        }
703
704        let mut deg = 0.0f64;
705        let mut idx = 0;
706        if deg_ex {
707            deg = str_to_f64(parts[idx])?;
708            idx += 1;
709        }
710        if min_ex {
711            let min = str_to_f64(parts[idx])?;
712            deg += min / 60.0;
713            idx += 1;
714        }
715        if sec_ex {
716            let sec = str_to_f64(parts[idx])?;
717            deg += sec / 3600.0;
718        }
719        Ok(Value::Float(deg * consts::PI / 180.0))
720    }
721
722    /// Convert &str to complex number
723    /// Supported formats:
724    /// * "post" marker - `1+2i`
725    /// * *pre" marker - `1+i2`
726    ///
727    /// `i` can be capital one. Instead of `i` letter `j` can be used.
728    ///
729    /// Note: while omitting real part is supported by this converter(e.g,
730    /// it parses `2i` to `0+2i`), it is discouraged. Because a parser that
731    /// parses the entire expression cannot detect such cases and may generate
732    /// an error.
733    ///
734    /// Comma(,) can be used instead of decimal point(.):
735    /// `1.25d` is the same as `1,25d`
736    ///
737    /// For convenience digits can be separated with underscores:
738    /// `3_005.245_1d` is the same as `3005.2451d`
739    pub fn from_str_complex(s: &str) -> CalcResult {
740        let s = s.replace("_", "");
741        let s = s.replace(",", ".");
742        if let Some(pos) = s.find(|c: char| c == 'i' || c == 'I' || c == 'j' || c == 'J') {
743            if pos == 0 {
744                // only imaginary case: -i3.2e-5
745                let f = str_to_f64(&s[pos + 1..])?;
746                Ok(Value::Complex(Complex::new(0.0, f)))
747            } else if pos == 1 {
748                // imaginary and sign: -i3.2e-5
749                let mut f = str_to_f64(&s[pos + 1..])?;
750                if s.starts_with('-') {
751                    f = -f
752                }
753                Ok(Value::Complex(Complex::new(0.0, f)))
754            } else if pos == s.len() - 1 {
755                // harder case: -2.1e-4-3.2-e5i
756                let epos = s.rfind(|c: char| c == 'e' || c == 'E').unwrap_or_else(|| s.len());
757                let mut spos = s.rfind(|c: char| c == '-' || c == '+').unwrap_or_else(|| s.len());
758                if spos > epos {
759                    // case when the imaginary number has 'e' power: '..-2.3e-4i'.
760                    // need to look for the next '-' or '+' from the end
761                    spos = s[..epos].rfind(|c: char| c == '-' || c == '+').unwrap_or_else(|| s.len());
762                }
763                if spos >= epos || spos == 0 {
764                    let f = str_to_f64(&s[..s.len() - 1])?;
765                    return Ok(Value::Complex(Complex::new(0.0, f)));
766                }
767                let r = str_to_f64(&s[..spos])?;
768                let i = str_to_f64(&s[spos..s.len() - 1])?;
769                Ok(Value::Complex(Complex::new(r, i)))
770            } else {
771                // easier case: -2.1e-4+i3.2e-5
772                let r = str_to_f64(&s[..pos - 1])?;
773                let mut i = str_to_f64(&s[pos + 1..])?;
774                if &s[pos - 1..pos] == "-" {
775                    i = -i;
776                }
777                Ok(Value::Complex(Complex::new(r, i)))
778            }
779        } else {
780            let f = str_to_f64(&s)?;
781            Ok(Value::Complex(Complex::new(f, 0.0)))
782        }
783    }
784
785    //---------------------------------------------
786
787    /// Returns true if the value is zero
788    pub fn is_zero(&self) -> bool {
789        match self {
790            Value::Int(ref i) => i.is_zero(),
791            Value::Float(ref f) => *f == 0.0,
792            Value::Ratio(ref r) => r.is_zero(),
793            Value::Complex(ref c) => c.is_zero(),
794        }
795    }
796
797    /// Returns true if the value is zero or greater
798    pub fn is_positive(&self) -> bool {
799        match self {
800            Value::Int(ref i) => *i >= BigInt::zero(),
801            Value::Float(ref f) => *f >= 0.0f64,
802            Value::Ratio(ref r) => *r >= BigRational::zero(),
803            Value::Complex(ref c) => c.re >= 0.0f64,
804        }
805    }
806
807    // to check any value after any operation whether it can be converted
808    // to BigInt
809    fn is_like_int(&self) -> bool {
810        match self {
811            Value::Int(..) => true,
812            Value::Float(f) => {
813                let fa: f64 = f.abs();
814                // f64 precision is about 19-20 digits,
815                // so it is probable that any f64 > 1e20 is not precise
816                (1.0..=1e22).contains(&fa) && f64_equal(fa.floor(), fa)
817            }
818            Value::Ratio(ref r) => *r.denom() == BigInt::one(),
819            Value::Complex(ref c) => {
820                if c.im != 0.0 {
821                    return false;
822                }
823                let fa: f64 = c.re.abs();
824                (1.0..=1e22).contains(&fa) && f64_equal(fa.floor(), fa)
825            }
826        }
827    }
828
829    basic_op!(addition, +, false);
830    basic_op!(subtract, -, false);
831    basic_op!(multiply, *, false);
832
833    div_op!(divide, /, true);
834    div_op!(reminder, %, false);
835
836    /// Divides and truncates the result.
837    /// Note: the result is always big integer number even if
838    /// two complex numbers are divided. It means in that the result for
839    /// complex numbers may be incorrect or strange
840    pub fn div_int(self, rhs: Value) -> CalcResult {
841        if rhs.is_zero() {
842            return Err(CalcError::DividedByZero(format!("{}", self)));
843        }
844        match (&self, &rhs) {
845            (Value::Complex(..), ..) | (.., Value::Complex(..)) => {
846                let c2 = rhs.into_raw_complex()?;
847                let c1 = self.into_raw_complex()?;
848                let c = Value::Complex(c1 / c2);
849                Value::into_int(c)
850            }
851            (Value::Float(..), ..) | (.., Value::Float(..)) => {
852                let f2 = rhs.into_raw_f64()?;
853                let f1 = self.into_raw_f64()?;
854                let f = Value::Float(f1 / f2);
855                Value::into_int(f)
856            }
857            (Value::Ratio(..), ..) | (.., Value::Ratio(..)) => {
858                let r2 = rhs.into_raw_ratio()?;
859                let r1 = self.into_raw_ratio()?;
860                let r = Value::Ratio(r1 / r2);
861                Value::into_int(r)
862            }
863            _ => {
864                let i2 = rhs.into_raw_big_int()?;
865                let i1 = self.into_raw_big_int()?;
866                Ok(Value::Int(i1 / i2))
867            }
868        }
869    }
870
871    /// Inverts the sign of the value
872    pub fn negate(self) -> CalcResult {
873        match &self {
874            Value::Complex(c) => Ok(Value::Complex(-c)),
875            Value::Ratio(r) => Ok(Value::Ratio(-r)),
876            Value::Float(f) => Ok(Value::Float(-f)),
877            Value::Int(i) => Ok(Value::Int(-i)),
878        }
879    }
880
881    /// Calculates modulus of a complex number
882    pub fn norm(self) -> CalcResult {
883        let v = Value::into_complex(self)?;
884        match &v {
885            Value::Complex(c) => Ok(Value::Float(c.norm())),
886            _ => Err(CalcError::Unreachable),
887        }
888    }
889
890    /// Conjugates a complex number
891    pub fn conj(self) -> CalcResult {
892        match &self {
893            Value::Complex(c) => Ok(Value::Complex(c.conj())),
894            _ => Ok(self),
895        }
896    }
897
898    /// Returns imaginary part of a complex number
899    pub fn im(self) -> CalcResult {
900        match &self {
901            Value::Complex(c) => Ok(Value::Float(c.im)),
902            _ => Ok(Value::Float(0.0)),
903        }
904    }
905
906    /// Returns real part of a complex number
907    pub fn re(self) -> CalcResult {
908        match &self {
909            Value::Complex(c) => Ok(Value::Float(c.re)),
910            _ => Ok(self),
911        }
912    }
913
914    cmp_op!(eq, ==);
915    cmp_op!(less, <);
916    cmp_op!(lesseq, <=);
917    cmp_op_inv!(neq, eq, !=);
918    cmp_op_inv!(greater, lesseq, >);
919    cmp_op_inv!(greatereq, less, >=);
920
921    /// Inverts value as if it is a boolean one.
922    /// Since the library does not have dedicated type for boolean values,
923    /// big integers play their role. Rules of inversion:
924    /// * Any zero value -> `1`
925    /// * `0` in all other cases
926    pub fn logical_not(self) -> CalcResult {
927        if self.is_zero() {
928            Ok(Value::Int(BigInt::one()))
929        } else {
930            Ok(Value::Int(BigInt::zero()))
931        }
932    }
933
934    pub fn logical_and(self, rhs: Value) -> CalcResult {
935        if self.is_zero() || rhs.is_zero() {
936            Ok(Value::Int(BigInt::zero()))
937        } else {
938            Ok(Value::Int(BigInt::one()))
939        }
940    }
941
942    pub fn logical_or(self, rhs: Value) -> CalcResult {
943        if self.is_zero() && rhs.is_zero() {
944            Ok(Value::Int(BigInt::zero()))
945        } else {
946            Ok(Value::Int(BigInt::one()))
947        }
948    }
949
950    /// Extract fractional part of a float number
951    pub fn fract(self) -> CalcResult {
952        match &self {
953            Value::Complex(c) => Ok(Value::Complex(Complex::new(c.re.fract(), c.im.fract()))),
954            Value::Ratio(r) => Ok(Value::Ratio(r.fract())),
955            Value::Float(f) => Ok(Value::Float(f.fract())),
956            Value::Int(..) => Ok(Value::Int(BigInt::zero())),
957        }
958    }
959
960    /// Returns absolute value of a number
961    /// For complex numbers only its real part changes
962    pub fn abs(self) -> CalcResult {
963        match &self {
964            Value::Complex(c) => Ok(Value::Complex(Complex::new(c.re.abs(), c.im))),
965            Value::Ratio(r) => {
966                if *r < BigRational::zero() {
967                    Ok(Value::Ratio(-r))
968                } else {
969                    Ok(Value::Ratio(r.clone()))
970                }
971            }
972            Value::Float(f) => Ok(Value::Float(f.abs())),
973            Value::Int(i) => {
974                if *i < BigInt::zero() {
975                    Ok(Value::Int(-i))
976                } else {
977                    Ok(Value::Int(i.clone()))
978                }
979            }
980        }
981    }
982
983    round_op!(floor);
984    round_op!(ceil);
985    round_op!(round);
986    round_op!(trunc);
987
988    /// Squares the value.
989    /// Automatically converts complex number into float one if imaginary part
990    /// of the result is zero
991    pub fn sqr(self) -> CalcResult {
992        match &self {
993            Value::Complex(c) => {
994                let c = c * c;
995                if c.im == 0.0 {
996                    Ok(Value::Float(c.re))
997                } else {
998                    Ok(Value::Complex(c))
999                }
1000            }
1001            Value::Ratio(r) => Ok(Value::Ratio(r * r)),
1002            Value::Float(f) => Ok(Value::Float(f * f)),
1003            Value::Int(i) => Ok(Value::Int(i * i)),
1004        }
1005    }
1006
1007    /// Returns sign of the number (for complex number it is a sign of real part):
1008    /// * `1` for a number greater than `0`
1009    /// * `0` for zero number
1010    /// * `-1` for number less than `0`
1011    pub fn signum(self) -> CalcResult {
1012        match &self {
1013            Value::Complex(c) => {
1014                if c.re == 0.0 {
1015                    Ok(Value::Int(BigInt::zero()))
1016                } else if c.re > 0.0 {
1017                    Ok(Value::Int(BigInt::one()))
1018                } else {
1019                    Ok(Value::Int(-BigInt::one()))
1020                }
1021            }
1022            Value::Ratio(r) => {
1023                if r.is_zero() {
1024                    Ok(Value::Int(BigInt::zero()))
1025                } else if *r > BigRational::zero() {
1026                    Ok(Value::Int(BigInt::one()))
1027                } else {
1028                    Ok(Value::Int(-BigInt::one()))
1029                }
1030            }
1031            Value::Float(f) => {
1032                if *f == 0.0 {
1033                    Ok(Value::Int(BigInt::zero()))
1034                } else if *f > 0.0 {
1035                    Ok(Value::Int(BigInt::one()))
1036                } else {
1037                    Ok(Value::Int(-BigInt::one()))
1038                }
1039            }
1040            Value::Int(i) => {
1041                if i.is_zero() {
1042                    Ok(Value::Int(BigInt::zero()))
1043                } else if *i > BigInt::zero() {
1044                    Ok(Value::Int(BigInt::one()))
1045                } else {
1046                    Ok(Value::Int(-BigInt::one()))
1047                }
1048            }
1049        }
1050    }
1051
1052    /// Returns square root of a number.
1053    /// Automatically converts a negative number into complex one before calculation
1054    pub fn sqrt(self) -> CalcResult {
1055        match &self {
1056            Value::Complex(c) => Ok(Value::Complex(c.sqrt())),
1057            Value::Ratio(r) => {
1058                if *r >= BigRational::zero() {
1059                    let n1 = r.numer().sqrt();
1060                    let d1 = r.denom().sqrt();
1061                    if n1.clone() * n1.clone() == *r.numer() && d1.clone() * d1.clone() == *r.denom() {
1062                        return Ok(Value::Ratio(BigRational::new(n1, d1)));
1063                    }
1064                }
1065                let f = ratio_to_f64(r)?;
1066                if f >= 0.0 {
1067                    Ok(Value::Float(f.sqrt()))
1068                } else {
1069                    let f = -f;
1070                    let c = Complex::new(0.0, f.sqrt());
1071                    Ok(Value::Complex(c))
1072                }
1073            }
1074            Value::Float(f) => {
1075                if *f >= 0.0 {
1076                    Ok(Value::Float(f.sqrt()))
1077                } else {
1078                    let f = -f;
1079                    let c = Complex::new(0.0, f.sqrt());
1080                    Ok(Value::Complex(c))
1081                }
1082            }
1083            Value::Int(i) => {
1084                if *i < BigInt::zero() {
1085                    let i = -i;
1086                    let f = int_to_f64(&i)?;
1087                    Ok(Value::Complex(Complex::new(0.0, f.sqrt())))
1088                } else {
1089                    let sq = i.sqrt();
1090                    if sq.clone() * sq.clone() == *i {
1091                        Ok(Value::Int(sq))
1092                    } else {
1093                        let f = int_to_f64(i)?;
1094                        Ok(Value::Float(f.sqrt()))
1095                    }
1096                }
1097            }
1098        }
1099    }
1100
1101    /// Returns cubic root of a number.
1102    pub fn cbrt(self) -> CalcResult {
1103        match &self {
1104            Value::Complex(..) => self.power(Value::Float(1.0f64 / 3.0f64)),
1105            Value::Ratio(r) => {
1106                let f = ratio_to_f64(r)?;
1107                Ok(Value::Float(f.cbrt()))
1108            }
1109            Value::Float(f) => Ok(Value::Float(f.cbrt())),
1110            Value::Int(i) => {
1111                let cb = i.cbrt();
1112                if cb.clone() * cb.clone() * cb.clone() == *i {
1113                    return Ok(Value::Int(cb));
1114                }
1115                let f = int_to_f64(&i)?;
1116                Ok(Value::Float(f.cbrt()))
1117            }
1118        }
1119    }
1120
1121    fn fast_power(self, pow: BigInt) -> CalcResult {
1122        if pow.is_zero() {
1123            return Ok(Value::Int(BigInt::one()));
1124        }
1125        let mut pow = pow;
1126        let mut inv = false;
1127        let sgn = pow.sign();
1128        if sgn == Sign::Minus {
1129            inv = true;
1130            pow = -pow;
1131        }
1132
1133        let mut res = Value::Int(BigInt::one());
1134        let mut base = self;
1135        while pow > BigInt::zero() {
1136            if pow.clone() % BigInt::from(2) == BigInt::zero() {
1137                pow /= BigInt::from(2);
1138                base = base.clone().multiply(base.clone())?;
1139            } else {
1140                pow -= BigInt::one();
1141                res = res.multiply(base.clone())?;
1142            }
1143        }
1144        if inv {
1145            return Value::Int(BigInt::one()).divide(res);
1146        }
1147        if Value::is_like_int(&res) {
1148            res = Value::into_int(res)?
1149        }
1150        Ok(res)
1151    }
1152
1153    /// Raises a number into arbitrary power.
1154    /// Automatic conversion as `sqrt` does is not not supported yet.
1155    /// For integer power degrees the fast and accurate algorithm is used.
1156    /// For float degrees the power is calculated using `exp`
1157    pub fn power(self, rhs: Value) -> CalcResult {
1158        match (&self, &rhs) {
1159            (Value::Complex(..), ..) | (.., Value::Complex(..)) => {
1160                let v = self.into_raw_complex()?;
1161                let pow = rhs.into_raw_complex()?;
1162                Ok(Value::Complex(v.powc(pow)))
1163            }
1164            (.., Value::Float(..)) => {
1165                let f1 = self.into_raw_f64()?;
1166                let f2 = rhs.into_raw_f64()?;
1167                if f1 < 0.0 {
1168                    let c1 = Complex::new(f1, 0.0);
1169                    let c2 = Complex::new(f2, 0.0);
1170                    return Ok(Value::Complex(c1.powc(c2)));
1171                }
1172                let f1 = Value::Float(f1.powf(f2));
1173                if Value::is_like_int(&f1) {
1174                    return Value::into_int(f1);
1175                }
1176                Ok(f1)
1177            }
1178            (.., Value::Int(i)) => self.fast_power(i.clone()),
1179            _ => Err(CalcError::Unreachable),
1180        }
1181    }
1182
1183    /// Returns factorial of a number.
1184    /// Complex numbers generates an error.
1185    /// Calculation factorial of negative or float number using gamma function
1186    /// is not supported yet
1187    pub fn fact(self) -> CalcResult {
1188        if Value::is_zero(&self) {
1189            return Ok(Value::Int(BigInt::one()));
1190        }
1191
1192        match &self {
1193            Value::Complex(..) => Err(CalcError::NotForComplex("factorial".to_owned())),
1194            Value::Ratio(..) | Value::Float(..) => {
1195                if Value::is_like_int(&self) {
1196                    let i = Value::into_int(self)?;
1197                    let i = if let Value::Int(i1) = i {
1198                        i1
1199                    } else {
1200                        return Err(CalcError::Unreachable);
1201                    };
1202                    if i < BigInt::zero() {
1203                        return Err(CalcError::NotForNegativeInt("factorial".to_owned()));
1204                    }
1205                    let mut res = BigInt::one();
1206                    let mut cnt = BigInt::from(1);
1207                    while cnt <= i {
1208                        res *= cnt.clone();
1209                        cnt += BigInt::one();
1210                    }
1211                    return Ok(Value::Int(res));
1212                }
1213                // TODO: use gamma function
1214                Err(CalcError::NotSupportedYet("factorial".to_owned(), "float".to_owned()))
1215            }
1216            Value::Int(i) => {
1217                if *i < BigInt::zero() {
1218                    return Err(CalcError::NotForNegativeInt("factorial".to_owned()));
1219                }
1220                let mut res = BigInt::one();
1221                let mut cnt = BigInt::from(1);
1222                while cnt <= *i {
1223                    res *= cnt.clone();
1224                    cnt += BigInt::one();
1225                }
1226                Ok(Value::Int(res))
1227            }
1228        }
1229    }
1230
1231    bitwise_op!(bit_or, |);
1232    bitwise_op!(bit_and, &);
1233    bitwise_op!(bit_xor, ^);
1234    bitwise_shift_op!(bit_shl, <<);
1235    bitwise_shift_op!(bit_shr, >>);
1236
1237    pub fn bit_not(self) -> CalcResult {
1238        match &self {
1239            Value::Int(i1) => Ok(Value::Int(!i1)),
1240            _ => Err(CalcError::OnlyInt("bitwise not".to_string())),
1241        }
1242    }
1243
1244    sin_cos!(sin);
1245    sin_cos!(cos);
1246    pub fn tan(self) -> CalcResult {
1247        match &self {
1248            Value::Complex(c) => Ok(Value::Complex(c.tan())),
1249            _ => {
1250                let f = self.clone().into_raw_f64()?;
1251                let half = consts::PI / 2.0;
1252                let ipart = (f / half).trunc();
1253                if f64_equal(ipart * half, f) {
1254                    Err(CalcError::InvalidAgrument("tan".to_owned(), format!("{}", self)))
1255                } else {
1256                    Ok(Value::Float(f.tan()))
1257                }
1258            }
1259        }
1260    }
1261
1262    asin_cos!(asin);
1263    asin_cos!(acos);
1264    pub fn atan(self) -> CalcResult {
1265        match &self {
1266            Value::Complex(c) => Ok(Value::Complex(c.atan())),
1267            _ => {
1268                let f = self.into_raw_f64()?;
1269                Ok(Value::Float(f.atan()))
1270            }
1271        }
1272    }
1273
1274    fn_hyper!(sinh);
1275    fn_hyper!(cosh);
1276    fn_hyper!(tanh);
1277    fn_hyper!(asinh);
1278    fn_hyper!(acosh);
1279    fn_hyper!(exp);
1280    pub fn atanh(self) -> CalcResult {
1281        match &self {
1282            Value::Complex(c) => Ok(Value::Complex(c.atanh())),
1283            _ => {
1284                let f = self.clone().into_raw_f64()?;
1285                if (-1.0..=1.0).contains(&f) {
1286                    Ok(Value::Float(f.atanh()))
1287                } else {
1288                    Err(CalcError::InvalidAgrument("atanh".to_owned(), format!("{}", self)))
1289                }
1290            }
1291        }
1292    }
1293
1294    /// Returns natural logarithm of a number.
1295    /// Automatically converts a negative number to a complex one before calculation
1296    pub fn ln(self) -> CalcResult {
1297        if Value::is_zero(&self) {
1298            return Err(CalcError::InvalidAgrument("ln".to_owned(), format!("{}", self)));
1299        }
1300        match &self {
1301            Value::Complex(c) => Ok(Value::Complex(c.ln())),
1302            _ => {
1303                let f = self.clone().into_raw_f64()?;
1304                if f > 0.0 {
1305                    Ok(Value::Float(f.ln()))
1306                } else {
1307                    let cm = Complex::new(f, 0.0);
1308                    Ok(Value::Complex(cm.ln()))
1309                }
1310            }
1311        }
1312    }
1313
1314    /// Converts float or integer number into rational one.
1315    /// Complex numbers generate an error
1316    pub fn ratio(self) -> CalcResult {
1317        match &self {
1318            Value::Ratio(..) => Ok(self),
1319            Value::Int(i) => Ok(Value::Ratio(BigRational::new(i.clone(), BigInt::one()))),
1320            Value::Float(f) => {
1321                if let Some(r) = BigRational::from_float(*f) {
1322                    Ok(Value::Ratio(r))
1323                } else {
1324                    Err(CalcError::InvalidAgrument("ratio".to_owned(), format!("{}", f)))
1325                }
1326            }
1327            Value::Complex(..) => Err(CalcError::NotForComplex("ratio".to_string())),
1328        }
1329    }
1330
1331    /// Greatest common divisor
1332    pub fn gcd(self, rhs: Value) -> CalcResult {
1333        let mut v1 = self.into_raw_big_int()?;
1334        let mut v2 = rhs.into_raw_big_int()?;
1335        if v1 < BigInt::zero() {
1336            v1 = -v1;
1337        }
1338        if v2 < BigInt::zero() {
1339            v2 = -v2;
1340        }
1341
1342        loop {
1343            if v1.is_zero() {
1344                return Ok(Value::Int(v2));
1345            }
1346            if v2.is_zero() {
1347                return Ok(Value::Int(v1));
1348            }
1349            if v1 < v2 {
1350                std::mem::swap(&mut v1, &mut v2);
1351            }
1352
1353            let m = v1 % v2.clone();
1354            v1 = v2;
1355            v2 = m;
1356        }
1357    }
1358
1359    /// Least Common Multiple
1360    pub fn lcm(self, rhs: Value) -> CalcResult {
1361        let gcd = self.clone().gcd(rhs.clone())?;
1362        let gcd = gcd.into_raw_big_int()?;
1363        let mut v1 = self.into_raw_big_int()?;
1364        let mut v2 = rhs.into_raw_big_int()?;
1365        if v1 < BigInt::zero() {
1366            v1 = -v1;
1367        }
1368        if v2 < BigInt::zero() {
1369            v2 = -v2;
1370        }
1371
1372        Ok(Value::Int(v1 / gcd * v2))
1373    }
1374
1375    /// Is Value a prime number. Returns error if a value is not integer
1376    /// Naive and slow algorithm for large integers
1377    pub fn prime(self) -> CalcResult {
1378        let v = self.abs()?;
1379        let v = if let Value::Int(i) = v {
1380            i
1381        } else {
1382            return Err(CalcError::OnlyInt("is_prime".to_string()));
1383        };
1384
1385        let res = if v <= BigInt::one() {
1386            Value::Int(BigInt::zero())
1387        } else if v > BigInt::one() && v < BigInt::from(4) {
1388            Value::Int(BigInt::one())
1389        } else if v.clone() % BigInt::from(2) == BigInt::zero() {
1390            Value::Int(BigInt::zero())
1391        } else {
1392            let upto = v.sqrt();
1393            let mut curr = BigInt::from(3);
1394            let mut r = BigInt::one();
1395            while curr <= upto {
1396                if v.clone() % curr.clone() == BigInt::zero() {
1397                    r = BigInt::zero();
1398                    break;
1399                }
1400                curr += BigInt::from(2);
1401            }
1402            Value::Int(r)
1403        };
1404        Ok(res)
1405    }
1406}
1407
1408#[cfg(test)]
1409mod tests {
1410    use super::*;
1411    use std::f64::consts;
1412    #[test]
1413    fn test_int_str() {
1414        let v = Value::from_str_integer("10002");
1415        assert_eq!(v, Ok(Value::Int(BigInt::from(10002i64))));
1416        let v = Value::from_str_integer("10_00_2");
1417        assert_eq!(v, Ok(Value::Int(BigInt::from(10002i64))));
1418        let v = Value::from_str_integer("-10002");
1419        assert_eq!(v, Ok(Value::Int(BigInt::from(-10002i64))));
1420        let v = Value::from_str_integer("33e5");
1421        assert_eq!(v, Ok(Value::Int(BigInt::from(3300000i64))));
1422        let v = Value::from_str_integer("33E6");
1423        assert_eq!(v, Ok(Value::Int(BigInt::from(33000000i64))));
1424
1425        let v = Value::from_str_integer("0Xff");
1426        assert_eq!(v, Ok(Value::Int(BigInt::from(255i64))));
1427        let v = Value::from_str_integer("0xff");
1428        assert_eq!(v, Ok(Value::Int(BigInt::from(255i64))));
1429        let v = Value::from_str_integer("0O33");
1430        assert_eq!(v, Ok(Value::Int(BigInt::from(27i64))));
1431        let v = Value::from_str_integer("0o33");
1432        assert_eq!(v, Ok(Value::Int(BigInt::from(27i64))));
1433        let v = Value::from_str_integer("0B101");
1434        assert_eq!(v, Ok(Value::Int(BigInt::from(5i64))));
1435        let v = Value::from_str_integer("0b101");
1436        assert_eq!(v, Ok(Value::Int(BigInt::from(5i64))));
1437    }
1438    #[test]
1439    fn test_float_str() {
1440        let v = Value::from_str_float("10002");
1441        assert_eq!(v, Ok(Value::Float(10002.0f64)));
1442        let v = Value::from_str_float("10_00_2");
1443        assert_eq!(v, Ok(Value::Float(10002.0f64)));
1444        let v = Value::from_str_float("10_00_3.5");
1445        assert_eq!(v, Ok(Value::Float(10003.5f64)));
1446        let v = Value::from_str_float("10_00_3,5");
1447        assert_eq!(v, Ok(Value::Float(10003.5f64)));
1448        let v = Value::from_str_float("1.0002e5");
1449        assert_eq!(v, Ok(Value::Float(100020.0f64)));
1450        let v = Value::from_str_float("200e-2");
1451        assert_eq!(v, Ok(Value::Float(2.0f64)));
1452    }
1453    #[test]
1454    fn test_ratio_str() {
1455        let v = Value::from_str_ratio("1\\2");
1456        assert_eq!(v, Ok(Value::Ratio(BigRational::new(BigInt::one(), BigInt::from(2i64)))));
1457        let v = Value::from_str_ratio("3\\2\\10");
1458        assert_eq!(v, Ok(Value::Ratio(BigRational::new(BigInt::from(3i64 * 10i64 + 2i64), BigInt::from(10i64)))));
1459    }
1460    #[test]
1461    fn test_angle_str() {
1462        let coef: f64 = consts::PI / 180.0f64;
1463        let v = Value::from_str_angle("10d");
1464        assert_eq!(v, Ok(Value::Float(10f64 * coef)));
1465        let v = Value::from_str_angle("10°");
1466        assert_eq!(v, Ok(Value::Float(10f64 * coef)));
1467        let v = Value::from_str_angle("10.5d");
1468        assert_eq!(v, Ok(Value::Float(10.5f64 * coef)));
1469        let v = Value::from_str_angle("10d30m");
1470        assert_eq!(v, Ok(Value::Float(10.5f64 * coef)));
1471        let v = Value::from_str_angle("10d30m900s");
1472        assert_eq!(v, Ok(Value::Float(10.75f64 * consts::PI / 180.0f64)));
1473    }
1474    #[test]
1475    fn test_complex_str() {
1476        let v = Value::from_str_complex("10.0e-1+50e-3i");
1477        assert_eq!(v, Ok(Value::Complex(Complex::new(1.0f64, 0.05f64))));
1478        let v = Value::from_str_complex("10.0e1-50e2i");
1479        assert_eq!(v, Ok(Value::Complex(Complex::new(100.0f64, -5000.0f64))));
1480        let v = Value::from_str_complex("10.0e-1+50e-3j");
1481        assert_eq!(v, Ok(Value::Complex(Complex::new(1.0f64, 0.05f64))));
1482        let v = Value::from_str_complex("10.0e-1+50e-3I");
1483        assert_eq!(v, Ok(Value::Complex(Complex::new(1.0f64, 0.05f64))));
1484        let v = Value::from_str_complex("10.0e-1+50e-3J");
1485        assert_eq!(v, Ok(Value::Complex(Complex::new(1.0f64, 0.05f64))));
1486
1487        let v = Value::from_str_complex("10.0e-1-i50e-3");
1488        assert_eq!(v, Ok(Value::Complex(Complex::new(1.0f64, -0.05f64))));
1489        let v = Value::from_str_complex("10.0e1-i50e2");
1490        assert_eq!(v, Ok(Value::Complex(Complex::new(100.0f64, -5000.0f64))));
1491        let v = Value::from_str_complex("10.0e-1-j50e-3");
1492        assert_eq!(v, Ok(Value::Complex(Complex::new(1.0f64, -0.05f64))));
1493        let v = Value::from_str_complex("10.0e-1-I50e-3");
1494        assert_eq!(v, Ok(Value::Complex(Complex::new(1.0f64, -0.05f64))));
1495        let v = Value::from_str_complex("10.0e-1-J50e-3");
1496        assert_eq!(v, Ok(Value::Complex(Complex::new(1.0f64, -0.05f64))));
1497        let v = Value::from_str_complex("-10.0e-1-J50e-3");
1498        assert_eq!(v, Ok(Value::Complex(Complex::new(-1.0f64, -0.05f64))));
1499
1500        let v = Value::from_str_complex("-i50e-3");
1501        assert_eq!(v, Ok(Value::Complex(Complex::new(0.0f64, -0.05f64))));
1502        let v = Value::from_str_complex("j50e-3");
1503        assert_eq!(v, Ok(Value::Complex(Complex::new(0.0f64, 0.05f64))));
1504        let v = Value::from_str_complex("-50e-3J");
1505        assert_eq!(v, Ok(Value::Complex(Complex::new(0.0f64, -0.05f64))));
1506        let v = Value::from_str_complex("50e-3I");
1507        assert_eq!(v, Ok(Value::Complex(Complex::new(0.0f64, 0.05f64))));
1508        let v = Value::from_str_complex("-i50e3");
1509        assert_eq!(v, Ok(Value::Complex(Complex::new(0.0f64, -50000.0f64))));
1510        let v = Value::from_str_complex("j50e3");
1511        assert_eq!(v, Ok(Value::Complex(Complex::new(0.0f64, 50000.0f64))));
1512        let v = Value::from_str_complex("-50e3J");
1513        assert_eq!(v, Ok(Value::Complex(Complex::new(0.0f64, -50000.0f64))));
1514        let v = Value::from_str_complex("50e3I");
1515        assert_eq!(v, Ok(Value::Complex(Complex::new(0.0f64, 50000.0f64))));
1516    }
1517    #[test]
1518    fn test_to_str() {
1519        let v = Value::Int(BigInt::from(12345));
1520        assert_eq!(v.to_string(), "12345");
1521        let v = Value::Float(2.25f64);
1522        assert_eq!(v.to_string(), "2.25");
1523        let v = Value::Ratio(BigRational::new(BigInt::from(23), BigInt::from(35)));
1524        assert_eq!(v.to_string(), "23\\35");
1525        let v = Value::Ratio(BigRational::new(BigInt::from(23), BigInt::from(5)));
1526        assert_eq!(v.to_string(), "4\\3\\5");
1527        let v = Value::Complex(Complex::new(0.0, 1.25));
1528        assert_eq!(v.to_string(), "0.0+1.25i");
1529        let v = Value::Complex(Complex::new(4.5, -3.25));
1530        assert_eq!(v.to_string(), "4.5-3.25i");
1531    }
1532    #[test]
1533    fn test_convert_int() {
1534        let v = Value::Int(BigInt::from(123));
1535        let f = Value::into_float(v.clone());
1536        assert_eq!(f, Ok(Value::Float(123.0)));
1537        let f = Value::into_complex(v.clone());
1538        assert_eq!(f, Ok(Value::Complex(Complex::new(123.0, 0.0))));
1539        let f = Value::into_ratio(v.clone());
1540        assert_eq!(f, Ok(Value::Ratio(BigRational::new(BigInt::from(123), BigInt::one()))));
1541    }
1542    #[test]
1543    fn test_convert_float() {
1544        let v = Value::Float(12.5);
1545        let f = Value::into_int(v.clone());
1546        assert_eq!(f, Ok(Value::Int(BigInt::from(12))));
1547        let f = Value::into_complex(v.clone());
1548        assert_eq!(f, Ok(Value::Complex(Complex::new(12.5, 0.0))));
1549        let f = Value::into_ratio(v.clone());
1550        assert_eq!(f, Ok(Value::Ratio(BigRational::new(BigInt::from(25), BigInt::from(2)))));
1551    }
1552    #[test]
1553    fn test_convert_ratio() {
1554        let v = Value::Ratio(BigRational::new(BigInt::from(5), BigInt::from(2)));
1555        let f = Value::into_int(v.clone());
1556        assert_eq!(f, Ok(Value::Int(BigInt::from(2))));
1557        let f = Value::into_complex(v.clone());
1558        assert_eq!(f, Ok(Value::Complex(Complex::new(2.5, 0.0))));
1559        let f = Value::into_float(v.clone());
1560        assert_eq!(f, Ok(Value::Float(2.5)));
1561    }
1562    #[test]
1563    fn test_convert_complex() {
1564        let v = Value::Complex(Complex::new(2.5, 3.5));
1565        let f = Value::into_int(v.clone());
1566        assert_eq!(f, Ok(Value::Int(BigInt::from(2))));
1567        let f = Value::into_ratio(v.clone());
1568        assert_eq!(f, Ok(Value::Ratio(BigRational::new(BigInt::from(5), BigInt::from(2)))));
1569        let f = Value::into_float(v.clone());
1570        assert_eq!(f, Ok(Value::Float(2.5)));
1571    }
1572    #[test]
1573    fn test_add() {
1574        let v1 = Value::Int(BigInt::from(3));
1575        let v2 = Value::Int(BigInt::from(4));
1576        let r = v1.addition(v2);
1577        assert_eq!(r, Ok(Value::Int(BigInt::from(7))));
1578        let v1 = Value::Int(BigInt::from(3));
1579        let v2 = Value::Float(4.5);
1580        let r = v1.addition(v2);
1581        assert_eq!(r, Ok(Value::Float(7.5)));
1582        let v1 = Value::Int(BigInt::from(3));
1583        let v2 = Value::Ratio(BigRational::new(BigInt::from(4), BigInt::from(5)));
1584        let r = v1.addition(v2);
1585        assert_eq!(r, Ok(Value::Ratio(BigRational::new(BigInt::from(19), BigInt::from(5)))));
1586        let v1 = Value::Float(0.5);
1587        let v2 = Value::Complex(Complex::new(4.5, 5.0));
1588        let r = v1.addition(v2);
1589        assert_eq!(r, Ok(Value::Complex(Complex::new(5.0, 5.0))));
1590    }
1591    #[test]
1592    fn test_sub() {
1593        let v1 = Value::Int(BigInt::from(3));
1594        let v2 = Value::Int(BigInt::from(4));
1595        let r = v1.subtract(v2);
1596        assert_eq!(r, Ok(Value::Int(BigInt::from(-1))));
1597        let v1 = Value::Int(BigInt::from(3));
1598        let v2 = Value::Float(4.5);
1599        let r = v1.subtract(v2);
1600        assert_eq!(r, Ok(Value::Float(-1.5)));
1601        let v1 = Value::Int(BigInt::from(3));
1602        let v2 = Value::Ratio(BigRational::new(BigInt::from(4), BigInt::from(5)));
1603        let r = v1.subtract(v2);
1604        assert_eq!(r, Ok(Value::Ratio(BigRational::new(BigInt::from(11), BigInt::from(5)))));
1605        let v1 = Value::Float(0.5);
1606        let v2 = Value::Complex(Complex::new(4.5, 5.0));
1607        let r = v1.subtract(v2);
1608        assert_eq!(r, Ok(Value::Complex(Complex::new(-4.0, -5.0))));
1609    }
1610    #[test]
1611    fn test_mul() {
1612        let v1 = Value::Int(BigInt::from(3));
1613        let v2 = Value::Int(BigInt::from(4));
1614        let r = v1.multiply(v2);
1615        assert_eq!(r, Ok(Value::Int(BigInt::from(12))));
1616        let v1 = Value::Int(BigInt::from(3));
1617        let v2 = Value::Float(4.5);
1618        let r = v1.multiply(v2);
1619        assert_eq!(r, Ok(Value::Float(13.5)));
1620        let v1 = Value::Int(BigInt::from(3));
1621        let v2 = Value::Ratio(BigRational::new(BigInt::from(4), BigInt::from(5)));
1622        let r = v1.multiply(v2);
1623        assert_eq!(r, Ok(Value::Ratio(BigRational::new(BigInt::from(12), BigInt::from(5)))));
1624        let v1 = Value::Float(5.0);
1625        let v2 = Value::Complex(Complex::new(4.0, 1.0));
1626        let r = v1.multiply(v2);
1627        assert_eq!(r, Ok(Value::Complex(Complex::new(20.0, 5.0))));
1628    }
1629    #[test]
1630    fn test_div() {
1631        let v1 = Value::Int(BigInt::from(12));
1632        let v2 = Value::Int(BigInt::from(4));
1633        let r = v1.divide(v2);
1634        assert_eq!(r, Ok(Value::Int(BigInt::from(3))));
1635        let v1 = Value::Int(BigInt::from(3));
1636        let v2 = Value::Int(BigInt::from(4));
1637        let r = v1.divide(v2);
1638        assert_eq!(r, Ok(Value::Float(0.75)));
1639        let v1 = Value::Float(3.0);
1640        let v2 = Value::Float(1.5);
1641        let r = v1.divide(v2);
1642        assert_eq!(r, Ok(Value::Int(BigInt::from(2))));
1643        let v1 = Value::Int(BigInt::from(3));
1644        let v2 = Value::Ratio(BigRational::new(BigInt::from(4), BigInt::from(5)));
1645        let r = v1.divide(v2);
1646        assert_eq!(r, Ok(Value::Ratio(BigRational::new(BigInt::from(15), BigInt::from(4)))));
1647        let v1 = Value::Float(5.0);
1648        let v2 = Value::Complex(Complex::new(5.0, 5.0));
1649        let r = v1.divide(v2);
1650        assert_eq!(r, Ok(Value::Complex(Complex::new(0.5, -0.5))));
1651    }
1652    #[test]
1653    fn test_div_int() {
1654        let v1 = Value::Int(BigInt::from(12));
1655        let v2 = Value::Int(BigInt::from(4));
1656        let r = v1.div_int(v2);
1657        assert_eq!(r, Ok(Value::Int(BigInt::from(3))));
1658        let v1 = Value::Int(BigInt::from(3));
1659        let v2 = Value::Int(BigInt::from(4));
1660        let r = v1.div_int(v2);
1661        assert_eq!(r, Ok(Value::Int(BigInt::zero())));
1662        let v1 = Value::Float(3.0);
1663        let v2 = Value::Float(1.5);
1664        let r = v1.div_int(v2);
1665        assert_eq!(r, Ok(Value::Int(BigInt::from(2))));
1666        let v1 = Value::Float(5.0);
1667        let v2 = Value::Float(3.0);
1668        let r = v1.div_int(v2);
1669        assert_eq!(r, Ok(Value::Int(BigInt::one())));
1670        let v1 = Value::Int(BigInt::from(3));
1671        let v2 = Value::Ratio(BigRational::new(BigInt::from(4), BigInt::from(5)));
1672        let r = v1.div_int(v2);
1673        assert_eq!(r, Ok(Value::Int(BigInt::from(3))));
1674        let v1 = Value::Complex(Complex::new(50.0, 25.0));
1675        let v2 = Value::Float(5.0);
1676        let r = v1.div_int(v2);
1677        assert_eq!(r, Ok(Value::Int(BigInt::from(10))));
1678    }
1679    #[test]
1680    fn test_neg() {
1681        let v = Value::Int(BigInt::from(12)).negate();
1682        assert_eq!(v, Ok(Value::Int(BigInt::from(-12))));
1683        let v = Value::Float(3.4).negate();
1684        assert_eq!(v, Ok(Value::Float(-3.4)));
1685        let v = Value::Ratio(BigRational::new(BigInt::from(2), BigInt::from(5))).negate();
1686        assert_eq!(v, Ok(Value::Ratio(-BigRational::new(BigInt::from(2), BigInt::from(5)))));
1687        let v = Value::Complex(Complex::new(3.0, 4.0)).negate();
1688        assert_eq!(v, Ok(Value::Complex(Complex::new(-3.0, -4.0))));
1689    }
1690    #[test]
1691    fn test_conj() {
1692        let v = Value::Float(3.4).conj();
1693        assert_eq!(v, Ok(Value::Float(3.4)));
1694        let v = Value::Complex(Complex::new(3.0, 4.0)).conj();
1695        assert_eq!(v, Ok(Value::Complex(Complex::new(3.0, -4.0))));
1696    }
1697    #[test]
1698    fn test_eq() {
1699        let v1 = Value::Float(3.0);
1700        let v2 = Value::Int(BigInt::from(3));
1701        let v = v1.eq(v2);
1702        assert_eq!(v, Ok(Value::Int(BigInt::one())));
1703        let v1 = Value::Float(2.5);
1704        let v2 = Value::Ratio(BigRational::new(BigInt::from(5), BigInt::from(2)));
1705        let v = v1.eq(v2);
1706        assert_eq!(v, Ok(Value::Int(BigInt::one())));
1707        let v1 = Value::Complex(Complex::new(3.0, 2.0));
1708        let v2 = Value::Complex(Complex::new(3.0, 2.0));
1709        let v = v1.eq(v2);
1710        assert_eq!(v, Ok(Value::Int(BigInt::one())));
1711        let v1 = Value::Complex(Complex::new(3.0, 2.0));
1712        let v2 = Value::Float(3.0);
1713        let v = v1.eq(v2);
1714        assert_eq!(v, Ok(Value::Int(BigInt::zero())));
1715    }
1716    #[test]
1717    fn test_neq() {
1718        let v1 = Value::Float(3.0);
1719        let v2 = Value::Int(BigInt::from(3));
1720        let v = v1.neq(v2);
1721        assert_eq!(v, Ok(Value::Int(BigInt::zero())));
1722        let v1 = Value::Float(2.5);
1723        let v2 = Value::Ratio(BigRational::new(BigInt::from(5), BigInt::from(2)));
1724        let v = v1.neq(v2);
1725        assert_eq!(v, Ok(Value::Int(BigInt::zero())));
1726        let v1 = Value::Complex(Complex::new(3.0, 2.0));
1727        let v2 = Value::Complex(Complex::new(3.0, 2.0));
1728        let v = v1.neq(v2);
1729        assert_eq!(v, Ok(Value::Int(BigInt::zero())));
1730        let v1 = Value::Complex(Complex::new(3.0, 2.0));
1731        let v2 = Value::Float(3.0);
1732        let v = v1.neq(v2);
1733        assert_eq!(v, Ok(Value::Int(BigInt::one())));
1734    }
1735    #[test]
1736    fn test_less() {
1737        let v1 = Value::Float(3.0);
1738        let v2 = Value::Int(BigInt::from(4));
1739        let v = v1.less(v2);
1740        assert_eq!(v, Ok(Value::Int(BigInt::one())));
1741        let v1 = Value::Float(2.4);
1742        let v2 = Value::Ratio(BigRational::new(BigInt::from(5), BigInt::from(2)));
1743        let v = v1.less(v2);
1744        assert_eq!(v, Ok(Value::Int(BigInt::one())));
1745        let v1 = Value::Complex(Complex::new(3.1, 2.1));
1746        let v2 = Value::Complex(Complex::new(3.0, 2.0));
1747        let v = v1.less(v2);
1748        assert_eq!(v, Ok(Value::Int(BigInt::zero())));
1749        let v1 = Value::Complex(Complex::new(3.0, 2.0));
1750        let v2 = Value::Float(3.0);
1751        let v = v1.less(v2);
1752        assert_eq!(v, Ok(Value::Int(BigInt::zero())));
1753    }
1754    #[test]
1755    fn test_greater() {
1756        let v1 = Value::Float(3.0);
1757        let v2 = Value::Int(BigInt::from(4));
1758        let v = v1.greater(v2);
1759        assert_eq!(v, Ok(Value::Int(BigInt::zero())));
1760        let v1 = Value::Float(2.4);
1761        let v2 = Value::Ratio(BigRational::new(BigInt::from(5), BigInt::from(2)));
1762        let v = v1.greater(v2);
1763        assert_eq!(v, Ok(Value::Int(BigInt::zero())));
1764        let v1 = Value::Complex(Complex::new(3.1, 2.1));
1765        let v2 = Value::Complex(Complex::new(3.0, 2.0));
1766        let v = v1.greater(v2);
1767        assert_eq!(v, Ok(Value::Int(BigInt::one())));
1768        let v1 = Value::Complex(Complex::new(3.0, 2.0));
1769        let v2 = Value::Float(3.0);
1770        let v = v1.greater(v2);
1771        assert_eq!(v, Ok(Value::Int(BigInt::one())));
1772    }
1773    #[test]
1774    fn test_abs() {
1775        let v = Value::Float(3.0).abs();
1776        assert_eq!(v, Ok(Value::Float(3.0)));
1777        let v = Value::Float(-3.0).abs();
1778        assert_eq!(v, Ok(Value::Float(3.0)));
1779        let v = Value::Int(BigInt::from(3)).abs();
1780        assert_eq!(v, Ok(Value::Int(BigInt::from(3))));
1781        let v = Value::Int(BigInt::from(-3)).abs();
1782        assert_eq!(v, Ok(Value::Int(BigInt::from(3))));
1783        let v = Value::Ratio(BigRational::new(BigInt::from(3), BigInt::from(2))).abs();
1784        assert_eq!(v, Ok(Value::Ratio(BigRational::new(BigInt::from(3), BigInt::from(2)))));
1785        let v = Value::Ratio(BigRational::new(BigInt::from(-3), BigInt::from(2))).abs();
1786        assert_eq!(v, Ok(Value::Ratio(BigRational::new(BigInt::from(3), BigInt::from(2)))));
1787        let v = Value::Complex(Complex::new(3.0, -2.0)).abs();
1788        assert_eq!(v, Ok(Value::Complex(Complex::new(3.0, -2.0))));
1789        let v = Value::Complex(Complex::new(-3.0, -2.0)).abs();
1790        assert_eq!(v, Ok(Value::Complex(Complex::new(3.0, -2.0))));
1791    }
1792    #[test]
1793    fn test_sqr() {
1794        let v = Value::Complex(Complex::new(0.0, 3.0)).sqr();
1795        assert_eq!(v, Ok(Value::Float(-9.0)));
1796    }
1797    #[test]
1798    fn test_sqrt() {
1799        let v = Value::Int(BigInt::from(9)).sqrt();
1800        assert_eq!(v, Ok(Value::Int(BigInt::from(3))));
1801        let v = Value::Int(BigInt::from(2)).sqrt().unwrap();
1802        assert_eq!(v.clone().less(Value::Float(1.6)), Ok(Value::Int(BigInt::one())));
1803        assert_eq!(v.greater(Value::Float(1.3)), Ok(Value::Int(BigInt::one())));
1804        let v = Value::Float(0.5);
1805        let r = v.clone().sqr().unwrap().sqrt();
1806        assert_eq!(Ok(v), r);
1807        let v = Value::Float(-4.0);
1808        let r = v.sqrt();
1809        assert!(r.is_ok());
1810        let r = r.unwrap();
1811        assert_eq!(r, Value::Complex(Complex::new(0.0, 2.0)));
1812    }
1813    #[test]
1814    fn test_round() {
1815        let v = Value::Float(2.75);
1816        let a = v.clone().round();
1817        assert_eq!(a, Ok(Value::Int(BigInt::from(3))));
1818        let a = v.clone().ceil();
1819        assert_eq!(a, Ok(Value::Int(BigInt::from(3))));
1820        let a = v.clone().floor();
1821        assert_eq!(a, Ok(Value::Int(BigInt::from(2))));
1822        let v = Value::Ratio(BigRational::new(BigInt::from(9), BigInt::from(4)));
1823        let a = v.clone().round();
1824        assert_eq!(a, Ok(Value::Int(BigInt::from(2))));
1825        let a = v.clone().ceil();
1826        assert_eq!(a, Ok(Value::Int(BigInt::from(3))));
1827        let a = v.clone().floor();
1828        assert_eq!(a, Ok(Value::Int(BigInt::from(2))));
1829    }
1830    #[test]
1831    fn test_power() {
1832        let v = Value::Float(3.0);
1833        let pow = Value::Int(BigInt::from(3));
1834        let v = v.power(pow);
1835        assert_eq!(v, Ok(Value::Int(BigInt::from(27))));
1836        let v = Value::Ratio(BigRational::new(BigInt::from(2), BigInt::from(3)));
1837        let pow = Value::Int(BigInt::from(2));
1838        let v = v.power(pow);
1839        assert_eq!(v, Ok(Value::Ratio(BigRational::new(BigInt::from(4), BigInt::from(9)))));
1840        let v = Value::Float(3.0);
1841        let pow = Value::Float(2.0);
1842        let v = v.power(pow);
1843        assert_eq!(v, Ok(Value::Int(BigInt::from(9))));
1844    }
1845    #[test]
1846    fn test_factorial() {
1847        let v = Value::Float(3.0).fact();
1848        assert_eq!(v, Ok(Value::Int(BigInt::from(6))));
1849        let v = Value::Int(BigInt::from(5)).fact();
1850        assert_eq!(v, Ok(Value::Int(BigInt::from(120))));
1851    }
1852    #[test]
1853    fn test_bitwise() {
1854        let v = Value::Int(BigInt::from(4)).bit_or(Value::Int(BigInt::from(9)));
1855        assert_eq!(v, Ok(Value::Int(BigInt::from(13))));
1856        let v = Value::Int(BigInt::from(5)).bit_and(Value::Int(BigInt::from(14)));
1857        assert_eq!(v, Ok(Value::Int(BigInt::from(4))));
1858        let v = Value::Int(BigInt::from(5)).bit_xor(Value::Int(BigInt::from(14)));
1859        assert_eq!(v, Ok(Value::Int(BigInt::from(11))));
1860    }
1861    #[test]
1862    fn test_exp() {
1863        let v = Value::Float(0.5);
1864        let r = v.clone().exp().unwrap().ln();
1865        assert_eq!(Ok(v.clone()), r);
1866    }
1867    #[test]
1868    fn test_trigonometry() {
1869        let v = Value::Float(0.5);
1870        let r = v.clone().sin().unwrap().asin();
1871        assert_eq!(Ok(v.clone()), r);
1872        let r = v.clone().tan().unwrap().atan();
1873        assert_eq!(Ok(v), r);
1874    }
1875    #[test]
1876    fn test_img() {
1877        let v = Value::Complex(Complex::new(3.0, -4.0));
1878        let r = v.clone().im();
1879        assert_eq!(r, Ok(Value::Float(-4.0)));
1880        let r = v.clone().re();
1881        assert_eq!(r, Ok(Value::Float(3.0)));
1882        let r = v.clone().norm();
1883        assert_eq!(r, Ok(Value::Float(5.0)));
1884    }
1885}