#![warn(missing_docs)]
#![warn(rustdoc::missing_crate_level_docs)]
pub mod fprice;
pub mod number_theory;
pub use number_theory::{
abs, abs_integer, bernoulli, ceil, denominator, floor, frac, gcd, is_even, is_odd, is_prime,
lcm, modulo, next_prime, nth_prime, numerator, powmod, prev_prime, prime_count, primes_up_to,
rem, round, rounding::RoundingMode, signum, signum_integer, totient, trunc,
};
pub use fprice::{fprice, fprice_float};
pub use number_theory::traits::{Divisors, Gcd, Lcm};
pub use rug;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Error {
DivisionByZero,
Overflow,
InvalidArgument,
Interrupted,
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::DivisionByZero => write!(f, "division by zero"),
Self::Overflow => write!(f, "arithmetic overflow"),
Self::InvalidArgument => write!(f, "invalid argument"),
Self::Interrupted => write!(f, "computation interrupted"),
}
}
}
impl std::error::Error for Error {}
#[cfg(test)]
mod tests {
use super::*;
use rug::Integer;
#[test]
fn test_basic_gcd() {
let a = Integer::from(48);
let b = Integer::from(18);
assert_eq!(gcd(&[&a, &b]), 6);
}
#[test]
fn test_basic_lcm() {
let a = Integer::from(21);
let b = Integer::from(6);
assert_eq!(lcm(&[&a, &b]), 42);
}
#[test]
fn test_is_prime() {
assert!(is_prime(&Integer::from(17)));
assert!(!is_prime(&Integer::from(18)));
}
#[test]
fn test_totient() {
assert_eq!(totient(&Integer::from(10)), 4);
assert_eq!(totient(&Integer::from(7)), 6);
}
#[test]
fn test_rounding() {
assert_eq!(round(7, 3, RoundingMode::HalfToEven), 2);
assert_eq!(round(5, 2, RoundingMode::HalfToEven), 2);
}
}