use crate::rational_polynomial::RationalPolynomial;
use core::cmp::Ordering::{self, *};
use malachite_base::num::arithmetic::traits::Sign;
use malachite_base::num::logic::traits::SignificantBits;
use malachite_base::polynomial::Polynomial;
use malachite_nz::integer::Integer;
use malachite_nz::natural::Natural;
#[cfg_attr(dylint_lib = "malachite_lints", allow(use_cmp_product))]
pub(crate) fn cmp_coefficients_same_length(
xs: &[Integer],
x_den: &Natural,
ys: &[Integer],
y_den: &Natural,
) -> Ordering {
if x_den == y_den {
return xs.iter().rev().cmp(ys.iter().rev());
}
let x_den_bits = x_den.significant_bits();
let y_den_bits = y_den.significant_bits();
let scale_xs = *y_den != 1u32;
let scale_ys = *x_den != 1u32;
let x_multiplier = Integer::from(y_den);
let y_multiplier = Integer::from(x_den);
for (x, y) in xs.iter().rev().zip(ys.iter().rev()) {
let x_sign = x.sign();
let y_sign = y.sign();
if x_sign != y_sign {
return x_sign.cmp(&y_sign);
}
if x_sign == Equal {
continue;
}
let x_bits = y_den_bits + x.significant_bits();
let y_bits = x_den_bits + y.significant_bits();
let c = if x_bits + 1 < y_bits {
if x_sign == Greater { Less } else { Greater }
} else if y_bits + 1 < x_bits {
if x_sign == Greater { Greater } else { Less }
} else {
match (scale_xs, scale_ys) {
(true, true) => (x * &x_multiplier).cmp(&(y * &y_multiplier)),
(true, false) => (x * &x_multiplier).cmp(y),
(false, true) => x.cmp(&(y * &y_multiplier)),
(false, false) => x.cmp(y),
}
};
if c != Equal {
return c;
}
}
Equal
}
impl PartialOrd for RationalPolynomial {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for RationalPolynomial {
fn cmp(&self, other: &Self) -> Ordering {
if core::ptr::eq(self, other) {
return Equal;
}
let xs = self.numerator.coefficients_asc();
let ys = other.numerator.coefficients_asc();
match xs.len().cmp(&ys.len()) {
Equal => cmp_coefficients_same_length(xs, &self.denominator, ys, &other.denominator),
Greater => self.numerator.leading_coefficient().sign(),
Less => other.numerator.leading_coefficient().sign().reverse(),
}
}
}