Tests and fixes
All checks were successful
timw4mail/rusty-numbers/pipeline/head This commit looks good

This commit is contained in:
Timothy Warren 2020-03-05 16:24:33 -05:00
parent 437dcd34fb
commit 101a37b6bc
4 changed files with 44 additions and 15 deletions

View File

@ -1,3 +0,0 @@
FROM rust:latest
RUN cargo install cargo-tarpaulin

1
Jenkinsfile vendored
View File

@ -18,6 +18,7 @@ pipeline {
} }
stage('Coverage') { stage('Coverage') {
steps { steps {
sh "cargo clean"
sh "cargo install cargo-tarpaulin" sh "cargo install cargo-tarpaulin"
sh "make generate-coverage" sh "make generate-coverage"
} }

View File

@ -95,6 +95,7 @@ impl Add for BigInt {
type Output = Self; type Output = Self;
fn add(self, rhs: Self) -> Self::Output { fn add(self, rhs: Self) -> Self::Output {
// @TODO: handle signs
let mut out = BigInt::default(); let mut out = BigInt::default();
let u_digits = self.inner.len(); let u_digits = self.inner.len();
@ -112,14 +113,13 @@ impl Add for BigInt {
let b = *rhs.inner.get(i).unwrap_or(&0usize); let b = *rhs.inner.get(i).unwrap_or(&0usize);
let (res, overflowed) = a.overflowing_add(b); let (res, overflowed) = a.overflowing_add(b);
// assert!(!overflowed, "Expected to overflow: {:#?}", (res, overflowed));
if overflowed { if overflowed {
if i == 0 { if i == 0 {
out.inner[i] = res; out.inner[i] = res + carry;
} else { } else {
out.inner.push(res); out.inner.push(res + carry);
} }
carry = core::usize::MAX - res; carry = 1;
} else { } else {
if res < core::usize::MAX { if res < core::usize::MAX {
out.inner.push(res + carry); out.inner.push(res + carry);
@ -216,8 +216,9 @@ impl Not for BigInt {
fn not(self) -> Self::Output { fn not(self) -> Self::Output {
let mut flipped: Vec<usize> = Vec::with_capacity(self.inner.len()); let mut flipped: Vec<usize> = Vec::with_capacity(self.inner.len());
for (i, val) in self.inner.iter().enumerate() { for val in self.inner.iter() {
flipped[i] = val.reverse_bits(); let rev = !*val;
flipped.push(rev);
} }
BigInt { BigInt {
@ -255,11 +256,19 @@ mod tests {
); );
assert_eq!(sum.inner[1], 1usize, "most significant place should be 1"); assert_eq!(sum.inner[1], 1usize, "most significant place should be 1");
/* let a = BigInt::from(core::usize::MAX); let a = BigInt::from(core::usize::MAX);
let b = BigInt::from(1usize); let b = BigInt::from(1usize);
let sum = a + b; let sum = a + b;
assert_eq!(sum.inner[0], 0usize); assert_eq!(sum.inner[0], 0usize);
assert_eq!(sum.inner[1], 1usize); */ assert_eq!(sum.inner[1], 1usize);
}
#[test]
fn test_not() {
let a = BigInt::from(0u8);
let b = !a;
assert_eq!(b.inner[0], core::usize::MAX);
} }
#[test] #[test]

View File

@ -3,8 +3,7 @@
//! Playin' with Numerics in Rust //! Playin' with Numerics in Rust
#![forbid(unsafe_code)] #![forbid(unsafe_code)]
use std::f64::consts::PI; use std::f64::consts::{E, PI};
use std::f64::consts::E;
pub mod bigint; pub mod bigint;
pub mod num; pub mod num;
@ -175,11 +174,34 @@ pub fn factorial(n: usize) -> Option<u128> {
} }
} }
pub fn approx_factorial(n: f64) -> f64 { /// Approximates a factorial using Stirling's approximation
///
/// Based on https://en.wikipedia.org/wiki/Stirling's_approximation
///
/// Can approximate up to ~ 170.624!
///
/// Example:
/// ```rust
/// use rusty_numbers::approx_factorial;
///
/// let valid = approx_factorial(170.6); // Some(..)
/// # assert!(valid.is_some());
///
/// let invalid = approx_factorial(171.0); // None
/// # assert!(invalid.is_none());
/// ```
#[inline]
pub fn approx_factorial(n: f64) -> Option<f64> {
let power = (n / E).powf(n); let power = (n / E).powf(n);
let root = (PI * 2.0 * n).sqrt(); let root = (PI * 2.0 * n).sqrt();
power * root let res = power * root;
if res >= core::f64::MIN && res <= core::f64::MAX {
Some(res)
} else {
None
}
} }
#[cfg(test)] #[cfg(test)]