Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-compute/src/arithmetic/unsigned.rs
6939 views
1
use arrow::array::{PrimitiveArray as PArr, StaticArray};
2
use arrow::compute::utils::{combine_validities_and, combine_validities_and3};
3
use strength_reduce::*;
4
5
use super::PrimitiveArithmeticKernelImpl;
6
use crate::arity::{prim_binary_values, prim_unary_values};
7
use crate::comparisons::TotalEqKernel;
8
9
macro_rules! impl_unsigned_arith_kernel {
10
($T:ty, $StrRed:ty) => {
11
impl PrimitiveArithmeticKernelImpl for $T {
12
type TrueDivT = f64;
13
14
fn prim_wrapping_abs(lhs: PArr<$T>) -> PArr<$T> {
15
lhs
16
}
17
18
fn prim_wrapping_neg(lhs: PArr<$T>) -> PArr<$T> {
19
prim_unary_values(lhs, |x| x.wrapping_neg())
20
}
21
22
fn prim_wrapping_add(lhs: PArr<$T>, other: PArr<$T>) -> PArr<$T> {
23
prim_binary_values(lhs, other, |a, b| a.wrapping_add(b))
24
}
25
26
fn prim_wrapping_sub(lhs: PArr<$T>, other: PArr<$T>) -> PArr<$T> {
27
prim_binary_values(lhs, other, |a, b| a.wrapping_sub(b))
28
}
29
30
fn prim_wrapping_mul(lhs: PArr<$T>, other: PArr<$T>) -> PArr<$T> {
31
prim_binary_values(lhs, other, |a, b| a.wrapping_mul(b))
32
}
33
34
fn prim_wrapping_floor_div(mut lhs: PArr<$T>, mut other: PArr<$T>) -> PArr<$T> {
35
let mask = other.tot_ne_kernel_broadcast(&0);
36
let valid = combine_validities_and3(
37
lhs.take_validity().as_ref(), // Take validity so we don't
38
other.take_validity().as_ref(), // compute combination twice.
39
Some(&mask),
40
);
41
let ret = prim_binary_values(lhs, other, |a, b| if b != 0 { a / b } else { 0 });
42
ret.with_validity(valid)
43
}
44
45
fn prim_wrapping_trunc_div(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {
46
Self::prim_wrapping_floor_div(lhs, rhs)
47
}
48
49
fn prim_wrapping_mod(mut lhs: PArr<$T>, mut other: PArr<$T>) -> PArr<$T> {
50
let mask = other.tot_ne_kernel_broadcast(&0);
51
let valid = combine_validities_and3(
52
lhs.take_validity().as_ref(), // Take validity so we don't
53
other.take_validity().as_ref(), // compute combination twice.
54
Some(&mask),
55
);
56
let ret = prim_binary_values(lhs, other, |a, b| if b != 0 { a % b } else { 0 });
57
ret.with_validity(valid)
58
}
59
60
fn prim_wrapping_add_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {
61
prim_unary_values(lhs, |x| x.wrapping_add(rhs))
62
}
63
64
fn prim_wrapping_sub_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {
65
Self::prim_wrapping_add_scalar(lhs, rhs.wrapping_neg())
66
}
67
68
fn prim_wrapping_sub_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<$T> {
69
prim_unary_values(rhs, |x| lhs.wrapping_sub(x))
70
}
71
72
fn prim_wrapping_mul_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {
73
if rhs == 0 {
74
lhs.fill_with(0)
75
} else if rhs == 1 {
76
lhs
77
} else if rhs.is_power_of_two() {
78
// Power of two.
79
let shift = rhs.trailing_zeros();
80
prim_unary_values(lhs, |x| x << shift)
81
} else {
82
prim_unary_values(lhs, |x| x.wrapping_mul(rhs))
83
}
84
}
85
86
fn prim_wrapping_floor_div_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {
87
if rhs == 0 {
88
PArr::full_null(lhs.len(), lhs.dtype().clone())
89
} else if rhs == 1 {
90
lhs
91
} else {
92
let red = <$StrRed>::new(rhs);
93
prim_unary_values(lhs, |x| x / red)
94
}
95
}
96
97
fn prim_wrapping_floor_div_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<$T> {
98
let mask = rhs.tot_ne_kernel_broadcast(&0);
99
let valid = combine_validities_and(rhs.validity(), Some(&mask));
100
let ret = if lhs == 0 {
101
rhs.fill_with(0)
102
} else {
103
prim_unary_values(rhs, |x| if x != 0 { lhs / x } else { 0 })
104
};
105
ret.with_validity(valid)
106
}
107
108
fn prim_wrapping_trunc_div_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {
109
Self::prim_wrapping_floor_div_scalar(lhs, rhs)
110
}
111
112
fn prim_wrapping_trunc_div_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<$T> {
113
Self::prim_wrapping_floor_div_scalar_lhs(lhs, rhs)
114
}
115
116
fn prim_wrapping_mod_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {
117
if rhs == 0 {
118
PArr::full_null(lhs.len(), lhs.dtype().clone())
119
} else if rhs == 1 {
120
lhs.fill_with(0)
121
} else {
122
let red = <$StrRed>::new(rhs);
123
prim_unary_values(lhs, |x| x % red)
124
}
125
}
126
127
fn prim_wrapping_mod_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<$T> {
128
let mask = rhs.tot_ne_kernel_broadcast(&0);
129
let valid = combine_validities_and(rhs.validity(), Some(&mask));
130
let ret = if lhs == 0 {
131
rhs.fill_with(0)
132
} else {
133
prim_unary_values(rhs, |x| if x != 0 { lhs % x } else { 0 })
134
};
135
ret.with_validity(valid)
136
}
137
138
fn prim_checked_mul_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {
139
super::prim_checked_mul_scalar(&lhs, rhs)
140
}
141
142
fn prim_true_div(lhs: PArr<$T>, other: PArr<$T>) -> PArr<Self::TrueDivT> {
143
prim_binary_values(lhs, other, |a, b| a as f64 / b as f64)
144
}
145
146
fn prim_true_div_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<Self::TrueDivT> {
147
let inv = 1.0 / rhs as f64;
148
prim_unary_values(lhs, |x| x as f64 * inv)
149
}
150
151
fn prim_true_div_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<Self::TrueDivT> {
152
prim_unary_values(rhs, |x| lhs as f64 / x as f64)
153
}
154
}
155
};
156
}
157
158
impl_unsigned_arith_kernel!(u8, StrengthReducedU8);
159
impl_unsigned_arith_kernel!(u16, StrengthReducedU16);
160
impl_unsigned_arith_kernel!(u32, StrengthReducedU32);
161
impl_unsigned_arith_kernel!(u64, StrengthReducedU64);
162
impl_unsigned_arith_kernel!(u128, StrengthReducedU128);
163
164