arrow2/compute/arithmetics/basic/
div.rs1use std::ops::Div;
3
4use num_traits::{CheckedDiv, NumCast};
5
6use crate::datatypes::PrimitiveType;
7use crate::{
8 array::{Array, PrimitiveArray},
9 compute::{
10 arithmetics::{ArrayCheckedDiv, ArrayDiv},
11 arity::{binary, binary_checked, unary, unary_checked},
12 utils::check_same_len,
13 },
14};
15use strength_reduce::{
16 StrengthReducedU16, StrengthReducedU32, StrengthReducedU64, StrengthReducedU8,
17};
18
19use super::NativeArithmetics;
20
21pub fn div<T>(lhs: &PrimitiveArray<T>, rhs: &PrimitiveArray<T>) -> PrimitiveArray<T>
36where
37 T: NativeArithmetics + Div<Output = T>,
38{
39 if rhs.null_count() == 0 {
40 binary(lhs, rhs, lhs.data_type().clone(), |a, b| a / b)
41 } else {
42 check_same_len(lhs, rhs).unwrap();
43 let values = lhs.iter().zip(rhs.iter()).map(|(l, r)| match (l, r) {
44 (Some(l), Some(r)) => Some(*l / *r),
45 _ => None,
46 });
47
48 PrimitiveArray::from_trusted_len_iter(values).to(lhs.data_type().clone())
49 }
50}
51
52pub fn checked_div<T>(lhs: &PrimitiveArray<T>, rhs: &PrimitiveArray<T>) -> PrimitiveArray<T>
68where
69 T: NativeArithmetics + CheckedDiv<Output = T>,
70{
71 let op = move |a: T, b: T| a.checked_div(&b);
72
73 binary_checked(lhs, rhs, lhs.data_type().clone(), op)
74}
75
76impl<T> ArrayDiv<PrimitiveArray<T>> for PrimitiveArray<T>
78where
79 T: NativeArithmetics + Div<Output = T>,
80{
81 fn div(&self, rhs: &PrimitiveArray<T>) -> Self {
82 div(self, rhs)
83 }
84}
85
86impl<T> ArrayCheckedDiv<PrimitiveArray<T>> for PrimitiveArray<T>
88where
89 T: NativeArithmetics + CheckedDiv<Output = T>,
90{
91 fn checked_div(&self, rhs: &PrimitiveArray<T>) -> Self {
92 checked_div(self, rhs)
93 }
94}
95
96pub fn div_scalar<T>(lhs: &PrimitiveArray<T>, rhs: &T) -> PrimitiveArray<T>
110where
111 T: NativeArithmetics + Div<Output = T> + NumCast,
112{
113 let rhs = *rhs;
114 match T::PRIMITIVE {
115 PrimitiveType::UInt64 => {
116 let lhs = lhs.as_any().downcast_ref::<PrimitiveArray<u64>>().unwrap();
117 let rhs = rhs.to_u64().unwrap();
118
119 let reduced_div = StrengthReducedU64::new(rhs);
120 let r = unary(lhs, |a| a / reduced_div, lhs.data_type().clone());
121 (&r as &dyn Array)
122 .as_any()
123 .downcast_ref::<PrimitiveArray<T>>()
124 .unwrap()
125 .clone()
126 }
127 PrimitiveType::UInt32 => {
128 let lhs = lhs.as_any().downcast_ref::<PrimitiveArray<u32>>().unwrap();
129 let rhs = rhs.to_u32().unwrap();
130
131 let reduced_div = StrengthReducedU32::new(rhs);
132 let r = unary(lhs, |a| a / reduced_div, lhs.data_type().clone());
133 (&r as &dyn Array)
134 .as_any()
135 .downcast_ref::<PrimitiveArray<T>>()
136 .unwrap()
137 .clone()
138 }
139 PrimitiveType::UInt16 => {
140 let lhs = lhs.as_any().downcast_ref::<PrimitiveArray<u16>>().unwrap();
141 let rhs = rhs.to_u16().unwrap();
142
143 let reduced_div = StrengthReducedU16::new(rhs);
144
145 let r = unary(lhs, |a| a / reduced_div, lhs.data_type().clone());
146 (&r as &dyn Array)
147 .as_any()
148 .downcast_ref::<PrimitiveArray<T>>()
149 .unwrap()
150 .clone()
151 }
152 PrimitiveType::UInt8 => {
153 let lhs = lhs.as_any().downcast_ref::<PrimitiveArray<u8>>().unwrap();
154 let rhs = rhs.to_u8().unwrap();
155
156 let reduced_div = StrengthReducedU8::new(rhs);
157 let r = unary(lhs, |a| a / reduced_div, lhs.data_type().clone());
158 (&r as &dyn Array)
159 .as_any()
160 .downcast_ref::<PrimitiveArray<T>>()
161 .unwrap()
162 .clone()
163 }
164 _ => unary(lhs, |a| a / rhs, lhs.data_type().clone()),
165 }
166}
167
168pub fn checked_div_scalar<T>(lhs: &PrimitiveArray<T>, rhs: &T) -> PrimitiveArray<T>
182where
183 T: NativeArithmetics + CheckedDiv<Output = T>,
184{
185 let rhs = *rhs;
186 let op = move |a: T| a.checked_div(&rhs);
187
188 unary_checked(lhs, op, lhs.data_type().clone())
189}
190
191impl<T> ArrayDiv<T> for PrimitiveArray<T>
193where
194 T: NativeArithmetics + Div<Output = T> + NumCast,
195{
196 fn div(&self, rhs: &T) -> Self {
197 div_scalar(self, rhs)
198 }
199}
200
201impl<T> ArrayCheckedDiv<T> for PrimitiveArray<T>
203where
204 T: NativeArithmetics + CheckedDiv<Output = T>,
205{
206 fn checked_div(&self, rhs: &T) -> Self {
207 checked_div_scalar(self, rhs)
208 }
209}