1#![forbid(unsafe_code)]
2pub use dashu_ratio::{RBig, Relaxed};
10pub use oxinum_core::{OxiNumError, OxiNumResult};
11
12pub use dashu_int::{IBig, UBig};
14
15pub type BigRational = RBig;
17
18mod convert;
19mod enumerate;
20mod ops;
21
22pub mod native;
29
30pub use convert::{from_f32, from_f64, parse_mixed, to_f64, to_f64_exact, MixedNumber};
31pub use enumerate::{farey_sequence, from_stern_brocot_path, stern_brocot_path};
32pub use ops::{
33 best_rational_approximation, continued_fraction, from_continued_fraction, mediant,
34 mixed_number, rational_abs, rational_ceil, rational_floor, rational_from_integer,
35 rational_is_integer, rational_pow, rational_reciprocal, rational_round, rational_signum,
36 rational_to_integer, rational_truncate, to_decimal_string,
37};
38
39#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn rbig_from_u32() {
49 let n = RBig::from(42u32);
50 assert_eq!(n.to_string(), "42");
51 }
52
53 #[test]
54 fn relaxed_from_u32() {
55 let n: Relaxed = Relaxed::from(42u32);
56 assert_eq!(n.to_string(), "42");
57 }
58
59 #[test]
60 fn rbig_from_parts_pi_approx() {
61 let r = RBig::from_parts(IBig::from(355), UBig::from(113u32));
62 assert_eq!(r.numerator(), &IBig::from(355));
63 assert_eq!(r.denominator(), &UBig::from(113u32));
64 assert_eq!(r.to_string(), "355/113");
65 }
66
67 #[test]
68 fn rbig_add_fractions() {
69 let half = RBig::from_parts(IBig::from(1), UBig::from(2u32));
71 let third = RBig::from_parts(IBig::from(1), UBig::from(3u32));
72 let sum = half + third;
73 assert_eq!(sum.numerator(), &IBig::from(5));
74 assert_eq!(sum.denominator(), &UBig::from(6u32));
75 }
76
77 #[test]
78 fn rbig_sub_fractions() {
79 let three_quarters = RBig::from_parts(IBig::from(3), UBig::from(4u32));
81 let one_quarter = RBig::from_parts(IBig::from(1), UBig::from(4u32));
82 let diff = three_quarters - one_quarter;
83 assert_eq!(diff.numerator(), &IBig::from(1));
84 assert_eq!(diff.denominator(), &UBig::from(2u32));
85 }
86
87 #[test]
88 fn rbig_mul() {
89 let a = RBig::from_parts(IBig::from(2), UBig::from(3u32));
91 let b = RBig::from_parts(IBig::from(3), UBig::from(4u32));
92 let product = a * b;
93 assert_eq!(product.numerator(), &IBig::from(1));
94 assert_eq!(product.denominator(), &UBig::from(2u32));
95 }
96
97 #[test]
98 fn rbig_div() {
99 let half = RBig::from_parts(IBig::from(1), UBig::from(2u32));
101 let third = RBig::from_parts(IBig::from(1), UBig::from(3u32));
102 let quotient = half / third;
103 assert_eq!(quotient.numerator(), &IBig::from(3));
104 assert_eq!(quotient.denominator(), &UBig::from(2u32));
105 }
106
107 #[test]
108 fn relaxed_canonicalize() {
109 let r = Relaxed::from_parts(IBig::from(-15), UBig::from(6u32));
110 assert_eq!(r.numerator(), &IBig::from(-15));
111 assert_eq!(r.denominator(), &UBig::from(6u32));
112 let canonical = r.canonicalize();
113 assert_eq!(canonical.numerator(), &IBig::from(-5));
114 assert_eq!(canonical.denominator(), &UBig::from(2u32));
115 }
116
117 #[test]
118 fn rbig_automatic_simplification() {
119 let r = RBig::from_parts(IBig::from(6), UBig::from(4u32));
121 assert_eq!(r.numerator(), &IBig::from(3));
122 assert_eq!(r.denominator(), &UBig::from(2u32));
123 }
124
125 #[test]
126 fn rbig_is_integer() {
127 let whole = RBig::from_parts(IBig::from(10), UBig::from(5u32));
128 assert_eq!(*whole.denominator(), UBig::ONE);
129
130 let frac = RBig::from_parts(IBig::from(1), UBig::from(3u32));
131 assert_ne!(*frac.denominator(), UBig::ONE);
132 }
133
134 #[test]
135 fn rbig_from_integer() {
136 let r = RBig::from(42u32);
137 assert_eq!(r.numerator(), &IBig::from(42));
138 assert_eq!(r.denominator(), &UBig::ONE);
139 }
140
141 #[test]
142 fn rbig_negation() {
143 let r = RBig::from_parts(IBig::from(3), UBig::from(4u32));
144 let neg = -r;
145 assert_eq!(neg.numerator(), &IBig::from(-3));
146 assert_eq!(neg.denominator(), &UBig::from(4u32));
147 }
148}