fraction/
prelude.rs

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