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') {
|
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"
|
||||||
}
|
}
|
||||||
|
@ -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]
|
||||||
|
30
src/lib.rs
30
src/lib.rs
@ -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)]
|
||||||
|
Loading…
Reference in New Issue
Block a user