use super::super::shared_docs::*;
use crate::{iif, paste, Int};
macro_rules! impl_div {
() => {
impl_div![signed
i8 :"_int_i8":"",
i16 :"_int_i16":"-1",
i32 :"_int_i32":"-2",
i64 :"_int_i64":"-3",
i128 :"_int_i128":"-4",
isize :"_int_isize":"-5"
];
impl_div![unsigned
u8 :"_int_u8" :"-6",
u16 :"_int_u16" :"-7",
u32 :"_int_u32" :"-8",
u64 :"_int_u64" :"-9",
u128 :"_int_u128" :"-10",
usize :"_int_usize" :"-11"
];
};
(signed $( $t:ty : $cap:literal : $d:literal ),+) => {
$( impl_div![@signed $t:$cap:$d]; )+
};
(unsigned $( $t:ty : $cap:literal : $d:literal ),+) => {
$( impl_div![@unsigned $t:$cap:$d]; )+
};
(
@signed $t:ty : $cap:literal : $d:literal) => { paste! {
#[doc = crate::doc_availability!(feature = $cap)]
#[doc = "# Integer division related methods for `" $t "`\n\n"]
#[doc = "- [div_rem](#method.div_rem" $d ")"]
#[doc = "- [div_ceil](#method.div_ceil" $d ")"]
#[doc = "- [div_floor](#method.div_floor" $d ")"]
#[doc = "- [div_ties_away](#method.div_ties_away" $d ")"]
#[doc = "- [div_ties_towards](#method.div_ties_towards" $d ")"]
#[doc = "- [div_ties_even](#method.div_ties_even" $d ")"]
#[doc = "- [div_ties_odd](#method.div_ties_odd" $d ")"]
#[cfg(feature = $cap )]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
impl Int<$t> {
#[must_use]
pub const fn div_rem(self, b: $t) -> [Int<$t>; 2] {
let a = self.0; [Int(a / b), Int(a % b)]
}
#[doc = NOTATION_DIV_CEIL!()]
#[doc = FORMULA_DIV_CEIL!()]
#[doc = "assert_eq![Int(7_" $t ").div_ceil(3), Int(3)]; // == 2.33…"]
#[doc = "assert_eq![Int(7_" $t ").div_ceil(-3), Int(-2)];"]
#[doc = "assert_eq![Int(-7_" $t ").div_ceil(3), Int(-2)];"]
#[doc = "assert_eq![Int(-7_" $t ").div_ceil(-3), Int(3)];"]
#[doc = "assert_eq![Int(7_" $t ").div_ceil(5), Int(2)]; // == 1.4"]
#[doc = "assert_eq![Int(6_" $t ").div_ceil(4), Int(2)]; // == 1.5"]
#[doc = "assert_eq![Int(8_" $t ").div_ceil(5), Int(2)]; // == 1.6"]
#[doc = "assert_eq![Int(5_" $t ").div_ceil(2), Int(3)]; // == 2.5"]
#[doc = "assert_eq![Int(-7_" $t ").div_ceil(5), Int(-1)]; // == -1.4"]
#[doc = "assert_eq![Int(-6_" $t ").div_ceil(4), Int(-1)]; // == -1.5"]
#[doc = "assert_eq![Int(-8_" $t ").div_ceil(5), Int(-1)]; // == -1.6"]
#[doc = "assert_eq![Int(-5_" $t ").div_ceil(2), Int(-2)]; // == -2.5"]
#[must_use]
pub const fn div_ceil(self, b: $t) -> Int<$t> {
let a = self.0; let (d, r) = (a / b, a % b);
iif![(r > 0 && b > 0) || (r < 0 && b < 0); Int(d + 1); Int(d)]
}
#[doc = NOTATION_DIV_FLOOR!()]
#[doc = "assert_eq![Int(7_" $t ").div_floor(3), Int(2)]; // == 2.33…"]
#[doc = "assert_eq![Int(7_" $t ").div_floor(-3), Int(-3)];"]
#[doc = "assert_eq![Int(-7_" $t ").div_floor(3), Int(-3)];"]
#[doc = "assert_eq![Int(-7_" $t ").div_floor(-3), Int(2)];"]
#[doc = "assert_eq![Int(7_" $t ").div_floor(5), Int(1)]; // == 1.4"]
#[doc = "assert_eq![Int(6_" $t ").div_floor(4), Int(1)]; // == 1.5"]
#[doc = "assert_eq![Int(8_" $t ").div_floor(5), Int(1)]; // == 1.6"]
#[doc = "assert_eq![Int(5_" $t ").div_floor(2), Int(2)]; // == 2.5"]
#[doc = "assert_eq![Int(-7_" $t ").div_floor(5), Int(-2)]; // == -1.4"]
#[doc = "assert_eq![Int(-6_" $t ").div_floor(4), Int(-2)]; // == -1.5"]
#[doc = "assert_eq![Int(-8_" $t ").div_floor(5), Int(-2)]; // == -1.6"]
#[doc = "assert_eq![Int(-5_" $t ").div_floor(2), Int(-3)]; // == -2.5"]
#[must_use]
pub const fn div_floor(self, b: $t) -> Int<$t> {
let a = self.0; let (d, r) = (a / b, a % b);
iif![(r > 0 && b < 0) || (r < 0 && b > 0); Int(d - 1); Int(d)]
}
#[doc = "assert_eq![Int(7_" $t ").div_ties_away(3), Int(2)]; // == 2.33…"]
#[doc = "assert_eq![Int(7_" $t ").div_ties_away(-3), Int(-2)];"]
#[doc = "assert_eq![Int(-7_" $t ").div_ties_away(3), Int(-2)];"]
#[doc = "assert_eq![Int(-7_" $t ").div_ties_away(-3), Int(2)];"]
#[doc = "assert_eq![Int(7_" $t ").div_ties_away(5), Int(1)]; // == 1.4"]
#[doc = "assert_eq![Int(6_" $t ").div_ties_away(4), Int(2)]; // == 1.5"]
#[doc = "assert_eq![Int(8_" $t ").div_ties_away(5), Int(2)]; // == 1.6"]
#[doc = "assert_eq![Int(5_" $t ").div_ties_away(2), Int(3)]; // == 2.5"]
#[doc = "assert_eq![Int(-7_" $t ").div_ties_away(5), Int(-1)]; // == -1.4"]
#[doc = "assert_eq![Int(-6_" $t ").div_ties_away(4), Int(-2)]; // == -1.5"]
#[doc = "assert_eq![Int(-8_" $t ").div_ties_away(5), Int(-2)]; // == -1.6"]
#[doc = "assert_eq![Int(-5_" $t ").div_ties_away(2), Int(-3)]; // == -2.5"]
#[must_use]
pub const fn div_ties_away(self, b: $t) -> Int<$t> {
let a = self.0; let (d, r) = (a / b, a % b);
iif![2 * r.abs() >= b.abs();
iif![(a > 0) == (b > 0); Int(d + 1); Int(d - 1)]; Int(d)]
}
#[doc = "assert_eq![Int(7_" $t ").div_ties_towards(3), Int(2)]; // == 2.33…"]
#[doc = "assert_eq![Int(7_" $t ").div_ties_towards(-3), Int(-2)];"]
#[doc = "assert_eq![Int(-7_" $t ").div_ties_towards(3), Int(-2)];"]
#[doc = "assert_eq![Int(-7_" $t ").div_ties_towards(-3), Int(2)];"]
#[doc = "assert_eq![Int(7_" $t ").div_ties_towards(5), Int(1)]; // == 1.4"]
#[doc = "assert_eq![Int(6_" $t ").div_ties_towards(4), Int(1)]; // == 1.5"]
#[doc = "assert_eq![Int(8_" $t ").div_ties_towards(5), Int(2)]; // == 1.6"]
#[doc = "assert_eq![Int(5_" $t ").div_ties_towards(2), Int(2)]; // == 2.5"]
#[doc = "assert_eq![Int(-7_" $t ").div_ties_towards(5), Int(-1)]; // == -1.4"]
#[doc = "assert_eq![Int(-6_" $t ").div_ties_towards(4), Int(-1)]; // == -1.5"]
#[doc = "assert_eq![Int(-8_" $t ").div_ties_towards(5), Int(-2)]; // == -1.6"]
#[doc = "assert_eq![Int(-5_" $t ").div_ties_towards(2), Int(-2)]; // == -2.5"]
#[must_use]
pub const fn div_ties_towards(self, b: $t) -> Int<$t> {
let a = self.0; let (d, r) = (a / b, a % b);
iif![2 * r.abs() > b.abs();
iif![(a > 0) == (b > 0); Int(d + 1); Int(d - 1)]; Int(d)]
}
#[doc = "assert_eq![Int(7_" $t ").div_ties_even(3), Int(2)]; // == 2.33…"]
#[doc = "assert_eq![Int(7_" $t ").div_ties_even(-3), Int(-2)];"]
#[doc = "assert_eq![Int(-7_" $t ").div_ties_even(3), Int(-2)];"]
#[doc = "assert_eq![Int(-7_" $t ").div_ties_even(-3), Int(2)];"]
#[doc = "assert_eq![Int(7_" $t ").div_ties_even(5), Int(1)]; // == 1.4"]
#[doc = "assert_eq![Int(6_" $t ").div_ties_even(4), Int(2)]; // == 1.5"]
#[doc = "assert_eq![Int(8_" $t ").div_ties_even(5), Int(2)]; // == 1.6"]
#[doc = "assert_eq![Int(5_" $t ").div_ties_even(2), Int(2)]; // == 2.5"]
#[doc = "assert_eq![Int(-7_" $t ").div_ties_even(5), Int(-1)]; // == -1.4"]
#[doc = "assert_eq![Int(-6_" $t ").div_ties_even(4), Int(-2)]; // == -1.5"]
#[doc = "assert_eq![Int(-8_" $t ").div_ties_even(5), Int(-2)]; // == -1.6"]
#[doc = "assert_eq![Int(-5_" $t ").div_ties_even(2), Int(-2)]; // == -2.5"]
#[must_use]
pub const fn div_ties_even(self, b: $t) -> Int<$t> {
let a = self.0; let (d, r) = (a / b, a % b);
iif![r == 0 || 2 * r.abs() < b.abs(); Int(d);
iif![2 * r.abs() > b.abs(); Int(d + a.signum() * b.signum());
iif![d % 2 == 0; Int(d); Int(d + a.signum() * b.signum())] ] ]
}
#[doc = "assert_eq![Int(7_" $t ").div_ties_odd(3), Int(2)]; // == 2.33…"]
#[doc = "assert_eq![Int(7_" $t ").div_ties_odd(-3), Int(-2)];"]
#[doc = "assert_eq![Int(-7_" $t ").div_ties_odd(3), Int(-2)];"]
#[doc = "assert_eq![Int(-7_" $t ").div_ties_odd(-3), Int(2)];"]
#[doc = "assert_eq![Int(7_" $t ").div_ties_odd(5), Int(1)]; // == 1.4"]
#[doc = "assert_eq![Int(6_" $t ").div_ties_odd(4), Int(1)]; // == 1.5"]
#[doc = "assert_eq![Int(8_" $t ").div_ties_odd(5), Int(2)]; // == 1.6"]
#[doc = "assert_eq![Int(5_" $t ").div_ties_odd(2), Int(3)]; // == 2.5"]
#[doc = "assert_eq![Int(-7_" $t ").div_ties_odd(5), Int(-1)]; // == -1.4"]
#[doc = "assert_eq![Int(-6_" $t ").div_ties_odd(4), Int(-1)]; // == -1.5"]
#[doc = "assert_eq![Int(-8_" $t ").div_ties_odd(5), Int(-2)]; // == -1.6"]
#[doc = "assert_eq![Int(-5_" $t ").div_ties_odd(2), Int(-3)]; // == -2.5"]
#[must_use]
pub const fn div_ties_odd(self, b: $t) -> Int<$t> {
let a = self.0; let (d, r) = (a / b, a % b);
iif![r == 0 || 2 * r.abs() < b.abs(); Int(d);
iif![2 * r.abs() > b.abs(); Int(d + a.signum() * b.signum());
iif![d % 2 != 0; Int(d); Int(d + a.signum() * b.signum())] ] ]
}
}
}};
(
@unsigned $t:ty : $cap:literal : $d:literal) => { paste! {
#[doc = crate::doc_availability!(feature = $cap)]
#[doc = "# Integer division related methods for `" $t "`\n\n"]
#[doc = "- [div_rem](#method.div_rem" $d ")"]
#[doc = "- [div_ceil](#method.div_ceil" $d ")"]
#[doc = "- [div_floor](#method.div_floor" $d ")"]
#[doc = "- [div_ties_away](#method.div_ties_away" $d ")"]
#[doc = "- [div_ties_towards](#method.div_ties_towards" $d ")"]
#[doc = "- [div_ties_even](#method.div_ties_even" $d ")"]
#[doc = "- [div_ties_odd](#method.div_ties_odd" $d ")"]
#[cfg(feature = $cap )]
impl Int<$t> {
#[must_use]
pub const fn div_rem(self, b: $t) -> [Int<$t>; 2] {
let a = self.0; [Int(a / b), Int(a % b)]
}
#[doc = NOTATION_DIV_CEIL!()]
#[doc = "assert_eq![Int(7_" $t ").div_ceil(3), Int(3)]; // == 2.33…"]
#[doc = "assert_eq![Int(7_" $t ").div_ceil(5), Int(2)]; // == 1.4"]
#[doc = "assert_eq![Int(6_" $t ").div_ceil(4), Int(2)]; // == 1.5"]
#[doc = "assert_eq![Int(8_" $t ").div_ceil(5), Int(2)]; // == 1.6"]
#[doc = "assert_eq![Int(5_" $t ").div_ceil(2), Int(3)]; // == 2.5"]
#[must_use]
pub const fn div_ceil(self, b: $t) -> Int<$t> {
let a = self.0; let (d, r) = (a / b, a % b);
iif![r > 0 && b > 0; Int(d + 1); Int(d)]
}
#[doc = NOTATION_DIV_FLOOR!()]
#[doc = "assert_eq![Int(7_" $t ").div_floor(3), Int(2)]; // == 2.33…"]
#[doc = "assert_eq![Int(7_" $t ").div_floor(5), Int(1)]; // == 1.4"]
#[doc = "assert_eq![Int(6_" $t ").div_floor(4), Int(1)]; // == 1.5"]
#[doc = "assert_eq![Int(8_" $t ").div_floor(5), Int(1)]; // == 1.6"]
#[doc = "assert_eq![Int(5_" $t ").div_floor(2), Int(2)]; // == 2.5"]
#[must_use]
pub const fn div_floor(self, b: $t) -> Int<$t> {
Int(self.0 / b)
}
#[doc = "assert_eq![Int(7_" $t ").div_ties_away(3), Int(2)]; // == 2.33…"]
#[doc = "assert_eq![Int(7_" $t ").div_ties_away(5), Int(1)]; // == 1.4"]
#[doc = "assert_eq![Int(6_" $t ").div_ties_away(4), Int(2)]; // == 1.5"]
#[doc = "assert_eq![Int(8_" $t ").div_ties_away(5), Int(2)]; // == 1.6"]
#[doc = "assert_eq![Int(5_" $t ").div_ties_away(2), Int(3)]; // == 2.5"]
#[must_use]
pub const fn div_ties_away(self, b: $t) -> Int<$t> {
let a = self.0; let (d, r) = (a / b, a % b);
iif![2 * r >= b; iif![a > b; Int(d + 1); Int(d - 1)]; Int(d)]
}
#[doc = "assert_eq![Int(7_" $t ").div_ties_towards(3), Int(2)]; // == 2.33…"]
#[doc = "assert_eq![Int(7_" $t ").div_ties_towards(5), Int(1)]; // == 1.4"]
#[doc = "assert_eq![Int(6_" $t ").div_ties_towards(4), Int(1)]; // == 1.5"]
#[doc = "assert_eq![Int(8_" $t ").div_ties_towards(5), Int(2)]; // == 1.6"]
#[doc = "assert_eq![Int(5_" $t ").div_ties_towards(2), Int(2)]; // == 2.5"]
#[must_use]
pub const fn div_ties_towards(self, b: $t) -> Int<$t> {
let a = self.0; let (d, r) = (a / b, a % b);
iif![2 * r > b; Int(d + 1); Int(d)]
}
#[doc = "assert_eq![Int(7_" $t ").div_ties_even(3), Int(2)]; // == 2.33…"]
#[doc = "assert_eq![Int(7_" $t ").div_ties_even(5), Int(1)]; // == 1.4"]
#[doc = "assert_eq![Int(6_" $t ").div_ties_even(4), Int(2)]; // == 1.5"]
#[doc = "assert_eq![Int(8_" $t ").div_ties_even(5), Int(2)]; // == 1.6"]
#[doc = "assert_eq![Int(5_" $t ").div_ties_even(2), Int(2)]; // == 2.5"]
#[must_use]
pub const fn div_ties_even(self, b: $t) -> Int<$t> {
let a = self.0; let (d, r) = (a / b, a % b);
iif![r == 0 || 2 * r < b; Int(d);
iif![2 * r > b; Int(d + 1);
iif![d % 2 == 0; Int(d); Int(d + 1)]]]
}
#[doc = "assert_eq![Int(7_" $t ").div_ties_odd(3), Int(2)]; // == 2.33…"]
#[doc = "assert_eq![Int(7_" $t ").div_ties_odd(5), Int(1)]; // == 1.4"]
#[doc = "assert_eq![Int(6_" $t ").div_ties_odd(4), Int(1)]; // == 1.5"]
#[doc = "assert_eq![Int(8_" $t ").div_ties_odd(5), Int(2)]; // == 1.6"]
#[doc = "assert_eq![Int(5_" $t ").div_ties_odd(2), Int(3)]; // == 2.5"]
#[must_use]
pub const fn div_ties_odd(self, b: $t) -> Int<$t> {
let a = self.0; let (d, r) = (a / b, a % b);
iif![r == 0 || 2 * r < b; Int(d);
iif![2 * r > b; Int(d + 1);
iif![d % 2 != 0; Int(d); Int(d + 1)]]]
}
}
}};
}
impl_div!();