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