Skip to content

Commit a303caf

Browse files
committed
implement round_ties_even for Ratio
1 parent 4d55ad2 commit a303caf

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

src/lib.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,46 @@ impl<T: Clone + Integer> Ratio<T> {
257257
}
258258
}
259259

260+
/// Rounds to the nearest integer. Rounds half-way cases away to even.
261+
pub fn round_ties_even(&self) -> Ratio<T> {
262+
let zero: Ratio<T> = Zero::zero();
263+
let one: T = One::one();
264+
let two: T = one.clone() + one.clone();
265+
266+
// Find unsigned fractional part of rational number
267+
let mut fractional = self.fract();
268+
if fractional < zero {
269+
fractional = zero - fractional
270+
};
271+
272+
// Compare the unsigned fractional part with 1/2
273+
let half = Ratio::new_raw(one, two);
274+
match fractional.cmp(&half) {
275+
cmp::Ordering::Greater => {
276+
let one: Ratio<T> = One::one();
277+
if *self >= Zero::zero() {
278+
self.trunc() + one
279+
} else {
280+
self.trunc() - one
281+
}
282+
}
283+
cmp::Ordering::Equal => {
284+
let trunc = self.trunc();
285+
if trunc.numer().is_even() {
286+
trunc
287+
} else {
288+
let one: Ratio<T> = One::one();
289+
if *self >= Zero::zero() {
290+
self.trunc() + one
291+
} else {
292+
self.trunc() - one
293+
}
294+
}
295+
}
296+
cmp::Ordering::Less => self.trunc(),
297+
}
298+
}
299+
260300
/// Rounds towards zero.
261301
#[inline]
262302
pub fn trunc(&self) -> Ratio<T> {

0 commit comments

Comments
 (0)