Tests and fixes
All checks were successful
timw4mail/rusty-numbers/pipeline/head This commit looks good
All checks were successful
timw4mail/rusty-numbers/pipeline/head This commit looks good
This commit is contained in:
parent
437dcd34fb
commit
101a37b6bc
@ -1,3 +0,0 @@
|
||||
FROM rust:latest
|
||||
|
||||
RUN cargo install cargo-tarpaulin
|
1
Jenkinsfile
vendored
1
Jenkinsfile
vendored
@ -18,6 +18,7 @@ pipeline {
|
||||
}
|
||||
stage('Coverage') {
|
||||
steps {
|
||||
sh "cargo clean"
|
||||
sh "cargo install cargo-tarpaulin"
|
||||
sh "make generate-coverage"
|
||||
}
|
||||
|
@ -95,6 +95,7 @@ impl Add for BigInt {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
// @TODO: handle signs
|
||||
let mut out = BigInt::default();
|
||||
|
||||
let u_digits = self.inner.len();
|
||||
@ -112,14 +113,13 @@ impl Add for BigInt {
|
||||
let b = *rhs.inner.get(i).unwrap_or(&0usize);
|
||||
|
||||
let (res, overflowed) = a.overflowing_add(b);
|
||||
// assert!(!overflowed, "Expected to overflow: {:#?}", (res, overflowed));
|
||||
if overflowed {
|
||||
if i == 0 {
|
||||
out.inner[i] = res;
|
||||
out.inner[i] = res + carry;
|
||||
} else {
|
||||
out.inner.push(res);
|
||||
out.inner.push(res + carry);
|
||||
}
|
||||
carry = core::usize::MAX - res;
|
||||
carry = 1;
|
||||
} else {
|
||||
if res < core::usize::MAX {
|
||||
out.inner.push(res + carry);
|
||||
@ -216,8 +216,9 @@ impl Not for BigInt {
|
||||
fn not(self) -> Self::Output {
|
||||
let mut flipped: Vec<usize> = Vec::with_capacity(self.inner.len());
|
||||
|
||||
for (i, val) in self.inner.iter().enumerate() {
|
||||
flipped[i] = val.reverse_bits();
|
||||
for val in self.inner.iter() {
|
||||
let rev = !*val;
|
||||
flipped.push(rev);
|
||||
}
|
||||
|
||||
BigInt {
|
||||
@ -255,11 +256,19 @@ mod tests {
|
||||
);
|
||||
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 sum = a + b;
|
||||
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]
|
||||
|
30
src/lib.rs
30
src/lib.rs
@ -3,8 +3,7 @@
|
||||
//! Playin' with Numerics in Rust
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
use std::f64::consts::PI;
|
||||
use std::f64::consts::E;
|
||||
use std::f64::consts::{E, PI};
|
||||
|
||||
pub mod bigint;
|
||||
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 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)]
|
||||
|
Loading…
Reference in New Issue
Block a user