fixed_bigint/fixeduint/
div_ceil_impl.rs1use super::{const_div, const_is_zero, FixedUInt, MachineWord};
18use crate::const_numtraits::{ConstCheckedAdd, ConstDivCeil, ConstOne};
19use crate::machineword::ConstMachineWord;
20
21c0nst::c0nst! {
22 impl<T: [c0nst] ConstMachineWord + MachineWord, const N: usize> c0nst ConstDivCeil for FixedUInt<T, N> {
23 fn div_ceil(self, rhs: Self) -> Self {
24 match self.checked_div_ceil(rhs) {
25 Some(v) => v,
26 None => panic!("div_ceil: division by zero or overflow"),
27 }
28 }
29
30 fn checked_div_ceil(self, rhs: Self) -> Option<Self> {
31 if const_is_zero(&rhs.array) {
32 return None;
33 }
34 let mut quotient = self.array;
36 let remainder = const_div(&mut quotient, &rhs.array);
37 if const_is_zero(&remainder) {
38 Some(Self { array: quotient })
39 } else {
40 ConstCheckedAdd::checked_add(&Self { array: quotient }, &Self::one())
42 }
43 }
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50
51 #[test]
52 fn test_div_ceil() {
53 type U16 = FixedUInt<u8, 2>;
54
55 assert_eq!(
57 ConstDivCeil::div_ceil(U16::from(10u8), U16::from(5u8)),
58 U16::from(2u8)
59 );
60 assert_eq!(
61 ConstDivCeil::div_ceil(U16::from(10u8), U16::from(2u8)),
62 U16::from(5u8)
63 );
64
65 assert_eq!(
67 ConstDivCeil::div_ceil(U16::from(10u8), U16::from(3u8)),
68 U16::from(4u8)
69 ); assert_eq!(
71 ConstDivCeil::div_ceil(U16::from(11u8), U16::from(3u8)),
72 U16::from(4u8)
73 ); assert_eq!(
75 ConstDivCeil::div_ceil(U16::from(12u8), U16::from(3u8)),
76 U16::from(4u8)
77 ); assert_eq!(
81 ConstDivCeil::div_ceil(U16::from(0u8), U16::from(5u8)),
82 U16::from(0u8)
83 );
84 assert_eq!(
85 ConstDivCeil::div_ceil(U16::from(1u8), U16::from(5u8)),
86 U16::from(1u8)
87 ); assert_eq!(
89 ConstDivCeil::div_ceil(U16::from(1u8), U16::from(1u8)),
90 U16::from(1u8)
91 );
92 }
93
94 #[test]
95 fn test_checked_div_ceil() {
96 type U16 = FixedUInt<u8, 2>;
97
98 assert_eq!(
99 ConstDivCeil::checked_div_ceil(U16::from(10u8), U16::from(3u8)),
100 Some(U16::from(4u8))
101 );
102
103 assert_eq!(
105 ConstDivCeil::checked_div_ceil(U16::from(10u8), U16::from(0u8)),
106 None
107 );
108
109 assert_eq!(
111 ConstDivCeil::checked_div_ceil(U16::from(65535u16), U16::from(2u16)),
112 Some(U16::from(32768u16))
113 );
114
115 assert_eq!(
117 ConstDivCeil::checked_div_ceil(U16::from(65535u16), U16::from(1u16)),
118 Some(U16::from(65535u16))
119 );
120 }
121
122 c0nst::c0nst! {
123 pub c0nst fn const_div_ceil<T: [c0nst] ConstMachineWord + MachineWord, const N: usize>(
124 a: FixedUInt<T, N>,
125 b: FixedUInt<T, N>,
126 ) -> FixedUInt<T, N> {
127 ConstDivCeil::div_ceil(a, b)
128 }
129 }
130
131 #[test]
132 fn test_const_div_ceil() {
133 type U16 = FixedUInt<u8, 2>;
134
135 assert_eq!(
136 const_div_ceil(U16::from(10u8), U16::from(3u8)),
137 U16::from(4u8)
138 );
139
140 #[cfg(feature = "nightly")]
141 {
142 const TEN: U16 = FixedUInt { array: [10, 0] };
143 const THREE: U16 = FixedUInt { array: [3, 0] };
144 const RESULT: U16 = const_div_ceil(TEN, THREE);
145 assert_eq!(RESULT, FixedUInt { array: [4, 0] });
146 }
147 }
148}