1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
//! Predefines some types for the most common use cases
//!
//! You should consider this module as a list of shortcuts, and not
//! as the list of only available types.
//! The actual workhorses are a part of the Public API and you are
//! encouraged to use them straightforwardly whenever you may
//! feel necessary.
//!
//! Long story short, you may compose your own types with these:
//! - [`GenericFraction`] for fractions
//! - [`GenericDecimal`] for decimals
//! - [`DynaInt`] integers on stack, but dynamically growing into heap when necessary
//!
//! [`GenericFraction`]: super::GenericFraction
//! [`GenericDecimal`]: super::GenericDecimal
//! [`DynaInt`]: super::dynaint
pub use super::fraction::GenericFraction;
#[cfg(feature = "with-bigint")]
pub use super::{BigInt, BigUint};
#[cfg(feature = "with-decimal")]
pub use super::decimal::GenericDecimal;
#[cfg(feature = "with-dynaint")]
pub use super::dynaint::DynaInt;
/// Fraction consisting from two `u64` numbers
///
/// Allows to keep and work with fractions on stack.
///
/// Be aware of possible stack overflows that might be caused by
/// exceeding `u64` limits in some math operations, which will make thread to panic.
///
/// # Examples
///
/// ```
/// use fraction::Fraction;
///
/// let first = Fraction::new (1u8, 2u8);
/// let second = Fraction::new (2u8, 8u8);
///
/// assert_eq! (first + second, Fraction::new (3u8, 4u8));
/// ```
pub type Fraction = GenericFraction<u64>;
/// Fraction consisting from two [`BigUint`] numbers
///
/// Allows to keep and work with fractions on heap.
///
/// BigUint number is based on heap and does not have any limits, which makes
/// BigFraction safe from stack overflows. However, it comes with a price of
/// making allocations on every math operation.
///
/// # Examples
///
/// ```
/// use fraction::BigFraction;
///
/// let first = BigFraction::new (2u8, 3u8);
/// let second = BigFraction::new (1u8, 6u8);
///
/// assert_eq! (first + second, BigFraction::new (5u8, 6u8));
/// ```
///
/// [`BigUint`]: https://docs.rs/num-bigint/*/num_bigint/
#[cfg(feature = "with-bigint")]
pub type BigFraction = GenericFraction<BigUint>;
/// Stack allocated, but dynamically growing into heap if necessary
///
/// Fraction using T as the base type for numerator and denominator
/// Whenever possible keeps data in T, but on math overflows
/// automatically casts values into BigUint, which allocates memory on heap.
///
/// Allows to use fractions without memory allocations wherever possible.
/// For unexpectedly big values performs on heap and doesn't suffer from stack overflows.
/// Automatically uses T if an operation on two BigUint numbers produces the result
/// that may fit within T.
///
/// # Examples
///
/// ```
/// use fraction::{DynaFraction, BigUint};
///
/// type D = DynaFraction<u32>;
///
/// let max_u32 = u32::max_value();
///
/// let one = D::from (1u32);
/// let mut val = D::from (max_u32);
///
/// assert_eq!( // check we still use u32 for the numerator
/// max_u32,
/// val.numer().unwrap().clone().unpack().ok().unwrap()
/// );
///
///
/// val += &one;
/// assert_eq!( // BigUint allocated for the result instead of stack overflow on u32
/// BigUint::from(max_u32) + BigUint::from(1u8),
/// val.numer().unwrap().clone().unpack().err().unwrap()
/// );
///
///
/// val -= one;
/// assert_eq!( // check we use u32 again
/// max_u32,
/// val.numer().unwrap().clone().unpack().ok().unwrap()
/// );
/// ```
#[cfg(all(feature = "with-bigint", feature = "with-dynaint"))]
pub type DynaFraction<T> = GenericFraction<DynaInt<T, BigUint>>;
/// Basic Decimal based on 2 u64 numbers and one u8 for precision.
/// Able to keep up to 19 digits in the number (including
/// both sides across the floating point).
///
/// # Examples
/// ```
/// use fraction::Decimal;
///
/// let one = Decimal::from(152.568);
/// let two = Decimal::from(328.76842);
///
/// assert_eq!(one + two, Decimal::from("481.33642"));
/// assert_eq!(two - one, Decimal::from("176.20042"));
/// assert_eq!(one * two, Decimal::from("50159.5403"));
/// assert_eq!(two / one, Decimal::from("2.15489"));
/// // the result takes the max precision (between 5 and 8 it goes with 8)
/// assert_eq!(two / one.set_precision(8), Decimal::from("2.15489761"))
/// ```
#[cfg(feature = "with-decimal")]
pub type Decimal = GenericDecimal<u64, u8>;
/// Heap allocated [`BigUint`] for numerics and `usize` for precision
///
/// # Examples
///
/// ```
/// use fraction::BigDecimal;
///
/// let one = BigDecimal::from(11.5);
/// let two = BigDecimal::from(30.5);
///
/// assert_eq!(one + two, BigDecimal::from(42));
/// ```
///
/// [`BigUint`]: https://docs.rs/num-bigint/*/num_bigint/
#[cfg(all(feature = "with-decimal", feature = "with-bigint"))]
pub type BigDecimal = GenericDecimal<BigUint, usize>;
/// Stack allocated, but dynamically growing into heap if necessary
///
/// Allows to use decimals without memory allocations wherever possible.
/// For unexpectedly big values performs on heap and doesn't suffer from stack overflows.
/// Automatically goes back onto T if an operation with [`BigUint`] numbers produces the result
/// that may fit within T.
///
/// # Examples
///
/// ```
/// use fraction::DynaDecimal;
///
/// type D = DynaDecimal<usize, u8>;
///
/// let d1 = D::from("0.462046206206402");
/// let d2 = D::from(12042002442022044usize);
///
/// let d3 = d2 / d1 * D::from(240);
///
/// assert_eq!(d3, D::from("6254960104129183747.885873163232639"));
/// ```
///
/// [`BigUint`]: https://docs.rs/num-bigint/*/num_bigint/
#[cfg(all(
feature = "with-decimal",
feature = "with-bigint",
feature = "with-dynaint"
))]
pub type DynaDecimal<T, P> = GenericDecimal<DynaInt<T, BigUint>, P>;