Skip to content

Commit

Permalink
Merge pull request #84 from squ1dd13/master
Browse files Browse the repository at this point in the history
`sqrt` implementation
  • Loading branch information
dnsl48 committed Sep 27, 2023
2 parents 7e35947 + d2dbc9f commit 679201d
Show file tree
Hide file tree
Showing 9 changed files with 941 additions and 9 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ exclude = ["src/tests/division/*"]
[package.metadata.docs.rs]
all-features = true

[profile.test]
opt-level = 3

[dependencies]

num = { version = "0.4", default-features = false }
Expand All @@ -44,6 +47,7 @@ default = ["with-bigint", "with-decimal", "with-dynaint"]
with-bigint = ["num/num-bigint", "num/std", "lazy_static"]
with-decimal = []
with-dynaint = []
with-approx = ["with-bigint"]

with-juniper-support = ["juniper"]
with-postgres-support = ["postgres-types", "byteorder", "bytes"]
Expand Down
46 changes: 38 additions & 8 deletions benches/bench_fraction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ use fraction::generic;
use fraction::{GenericDecimal, GenericFraction};
use std::str::FromStr;

#[allow(clippy::missing_panics_doc)]
pub fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("Decimal u128/u16 init", |b| {
b.iter(|| GenericDecimal::<u128, u16>::from(black_box(15978.649)))
b.iter(|| GenericDecimal::<u128, u16>::from(black_box(15978.649)));
});

c.bench_function("Decimal i64/u16 init", |b| {
Expand All @@ -16,7 +17,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
let b = GenericDecimal::<i64, u16>::from(black_box(-15978.649));

(a, b)
})
});
});

c.bench_function("Convert int like from str", |b| {
Expand All @@ -25,7 +26,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
let b = GenericFraction::<u8>::from_str(black_box("100"));

(a, b)
})
});
});

c.bench_function("Convert float like from str", |b| {
Expand All @@ -34,28 +35,57 @@ pub fn criterion_benchmark(c: &mut Criterion) {
let b = GenericFraction::<u8>::from_str(black_box("100.001"));

(a, b)
})
});
});

c.bench_function("Convert fraction like from str", |b| {
b.iter(|| {
let a = GenericFraction::<u8>::from_str(black_box("1/1"));
let b = GenericFraction::<u8>::from_str(black_box("255/255"));
(a, b)
})
});
});

c.bench_function("generic::read_generic_integer / i8 to u8", |b| {
b.iter(|| generic::read_generic_integer::<u8, i8>(black_box(14i8)).unwrap())
b.iter(|| generic::read_generic_integer::<u8, i8>(black_box(14i8)).unwrap());
});

c.bench_function("generic::read_generic_integer / u8 to u8", |b| {
b.iter(|| generic::read_generic_integer::<u8, u8>(black_box(14u8)).unwrap())
b.iter(|| generic::read_generic_integer::<u8, u8>(black_box(14u8)).unwrap());
});

c.bench_function("From couple", |b| {
b.iter(|| GenericFraction::<u8>::from(black_box((3u8, 4u8))))
b.iter(|| GenericFraction::<u8>::from(black_box((3u8, 4u8))));
});

#[cfg(feature = "with-approx")]
{
let num2 = GenericFraction::<u8>::from(2);
let small_num = fraction::BigFraction::new(1_u8, u128::MAX) / u128::MAX;
let big_num = fraction::BigFraction::new(u128::MAX, 1_u8) * u128::MAX;

let mut bench_dp = |n: u32| {
let mut group = c.benchmark_group(format!("Sqrt {n}dp raw"));

group.bench_function("2", |b| {
b.iter(|| num2.sqrt_raw(n));
});

group.bench_function("Small", |b| {
b.iter(|| small_num.sqrt_raw(n));
});

group.bench_function("Big", |b| {
b.iter(|| big_num.sqrt_raw(n));
});

group.finish();
};

bench_dp(10_000);
bench_dp(1_000);
bench_dp(100);
}
}

criterion_group!(benches, criterion_benchmark);
Expand Down
60 changes: 60 additions & 0 deletions src/decimal/approx.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use crate::{
approx::sqrt::RawApprox, fraction::approx::Accuracy, generic::GenericInteger, GenericDecimal,
};
use num::{
bigint::{ToBigInt, ToBigUint},
BigUint, Integer,
};
use std::borrow::Borrow;

impl<
T: Clone + Integer + ToBigUint + ToBigInt + GenericInteger,
P: Copy + Integer + Into<usize>,
> GenericDecimal<T, P>
{
/// See `GenericFraction::sqrt_abs_with_accuracy_raw`.
pub fn sqrt_abs_with_accuracy_raw(&self, accuracy: impl Borrow<Accuracy>) -> RawApprox {
self.0.sqrt_abs_with_accuracy_raw(accuracy)
}

/// See `GenericFraction::sqrt_abs_with_accuracy`.
pub fn sqrt_abs_with_accuracy(
&self,
accuracy: impl Borrow<Accuracy>,
) -> GenericDecimal<BigUint, P> {
GenericDecimal(self.0.sqrt_abs_with_accuracy(accuracy), self.1)
}

/// See `GenericFraction::sqrt_abs_raw`.
pub fn sqrt_abs_raw(&self, decimal_places: u32) -> RawApprox {
self.0.sqrt_abs_raw(decimal_places)
}

/// See `GenericFraction::sqrt_abs`.
pub fn sqrt_abs(&self, decimal_places: u32) -> GenericDecimal<BigUint, P> {
GenericDecimal(self.0.sqrt_abs(decimal_places), self.1)
}

/// See `GenericFraction::sqrt_with_accuracy_raw`.
pub fn sqrt_with_accuracy_raw(&self, accuracy: impl Borrow<Accuracy>) -> RawApprox {
self.0.sqrt_with_accuracy_raw(accuracy)
}

/// See `GenericFraction::sqrt_with_accuracy`.
pub fn sqrt_with_accuracy(
&self,
accuracy: impl Borrow<Accuracy>,
) -> GenericDecimal<BigUint, P> {
GenericDecimal(self.0.sqrt_with_accuracy(accuracy), self.1)
}

/// See `GenericFraction::sqrt_raw`.
pub fn sqrt_raw(&self, decimal_places: u32) -> RawApprox {
self.0.sqrt_raw(decimal_places)
}

/// See `GenericFraction::sqrt`.
pub fn sqrt(&self, decimal_places: u32) -> GenericDecimal<BigUint, P> {
GenericDecimal(self.0.sqrt(decimal_places), self.1)
}
}
5 changes: 4 additions & 1 deletion src/decimal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ mod postgres_support;
#[cfg(feature = "with-juniper-support")]
mod juniper_support;

#[cfg(feature = "with-approx")]
mod approx;

/// Decimal type implementation
///
/// T is the type for data
Expand Down Expand Up @@ -60,7 +63,7 @@ mod juniper_support;
/// ```
#[derive(Clone)]
#[cfg_attr(feature = "with-serde-support", derive(Serialize, Deserialize))]
pub struct GenericDecimal<T, P>(GenericFraction<T>, P)
pub struct GenericDecimal<T, P>(pub(crate) GenericFraction<T>, pub(crate) P)
where
T: Clone + Integer,
P: Copy + Integer + Into<usize>;
Expand Down
29 changes: 29 additions & 0 deletions src/dynaint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use std::mem;

use num::{
bigint::{ToBigInt, ToBigUint},
Bounded, CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, Integer, Num, One, ToPrimitive, Zero,
};
use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
Expand Down Expand Up @@ -886,6 +887,34 @@ where
dyna_impl!(impl_fn_refmath_tuple2self; div_rem);
}

#[cfg(feature = "with-bigint")]
impl<T, G> ToBigInt for DynaInt<T, G>
where
T: Copy + GenericInteger + Into<G> + TryToConvertFrom<G> + From<u8> + ToBigInt,
G: Clone + GenericInteger + ToBigInt,
{
fn to_bigint(&self) -> Option<num::BigInt> {
match self {
DynaInt::S(s) => s.to_bigint(),
DynaInt::__H(h) => h.to_bigint(),
}
}
}

#[cfg(feature = "with-bigint")]
impl<T, G> ToBigUint for DynaInt<T, G>
where
T: Copy + GenericInteger + Into<G> + TryToConvertFrom<G> + From<u8> + ToBigUint,
G: Clone + GenericInteger + ToBigUint,
{
fn to_biguint(&self) -> Option<num::BigUint> {
match self {
DynaInt::S(s) => s.to_biguint(),
DynaInt::__H(h) => h.to_biguint(),
}
}
}

#[cfg(test)]
mod tests {
use super::{
Expand Down

0 comments on commit 679201d

Please sign in to comment.