grass/src/value/number.rs

108 lines
2.3 KiB
Rust
Raw Normal View History

2020-02-08 18:43:18 -05:00
use std::convert::From;
use std::fmt::{self, Display, Write};
2020-02-08 20:20:03 -05:00
use std::ops::{Add, Div, Mul, Sub};
2020-02-08 18:43:18 -05:00
use num_bigint::BigInt;
use num_rational::BigRational;
const PRECISION: usize = 10;
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub(crate) struct Number {
val: BigRational,
}
impl Number {
pub const fn new(val: BigRational) -> Number {
Number { val }
}
pub fn to_integer(&self) -> BigInt {
self.val.to_integer()
}
}
impl From<BigInt> for Number {
fn from(b: BigInt) -> Self {
Number {
val: BigRational::from_integer(b),
}
}
}
impl From<u16> for Number {
fn from(b: u16) -> Self {
Number {
val: BigRational::from_integer(BigInt::from(b)),
}
}
}
2020-02-08 18:43:18 -05:00
impl Display for Number {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.val.to_integer())?;
let mut frac = self.val.fract();
if frac != BigRational::from_integer(BigInt::from(0)) {
f.write_char('.')?;
for _ in 0..PRECISION {
frac *= BigRational::from_integer(BigInt::from(10));
write!(f, "{}", frac.to_integer())?;
frac = frac.fract();
if frac == BigRational::from_integer(BigInt::from(0)) {
break;
}
}
2020-02-08 18:51:29 -05:00
if frac != BigRational::from_integer(BigInt::from(0)) {
2020-02-08 20:20:03 -05:00
write!(
f,
"{}",
(frac * BigRational::from_integer(BigInt::from(10)))
.round()
.to_integer()
)?;
2020-02-08 18:51:29 -05:00
}
2020-02-08 18:43:18 -05:00
}
Ok(())
}
}
impl Add for Number {
type Output = Self;
fn add(self, other: Self) -> Self {
Number {
val: self.val + other.val,
}
}
}
impl Sub for Number {
type Output = Self;
fn sub(self, other: Self) -> Self {
Number {
val: self.val - other.val,
}
}
}
impl Mul for Number {
type Output = Self;
fn mul(self, other: Self) -> Self {
Number {
val: self.val * other.val,
}
}
}
impl Div for Number {
type Output = Self;
fn div(self, other: Self) -> Self {
Number {
val: self.val / other.val,
}
}
}