Path: blob/main/crates/polars-compute/src/arithmetic/float.rs
6939 views
use arrow::array::PrimitiveArray as PArr;12use super::PrimitiveArithmeticKernelImpl;3use crate::arity::{prim_binary_values, prim_unary_values};45macro_rules! impl_float_arith_kernel {6($T:ty) => {7impl PrimitiveArithmeticKernelImpl for $T {8type TrueDivT = $T;910fn prim_wrapping_abs(lhs: PArr<$T>) -> PArr<$T> {11prim_unary_values(lhs, |x| x.abs())12}1314fn prim_wrapping_neg(lhs: PArr<$T>) -> PArr<$T> {15prim_unary_values(lhs, |x| -x)16}1718fn prim_wrapping_add(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {19prim_binary_values(lhs, rhs, |l, r| l + r)20}2122fn prim_wrapping_sub(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {23prim_binary_values(lhs, rhs, |l, r| l - r)24}2526fn prim_wrapping_mul(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {27prim_binary_values(lhs, rhs, |l, r| l * r)28}2930fn prim_wrapping_floor_div(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {31prim_binary_values(lhs, rhs, |l, r| (l / r).floor())32}3334fn prim_wrapping_trunc_div(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {35prim_binary_values(lhs, rhs, |l, r| (l / r).trunc())36}3738fn prim_wrapping_mod(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {39prim_binary_values(lhs, rhs, |l, r| l - r * (l / r).floor())40}4142fn prim_wrapping_add_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {43if rhs == 0.0 {44return lhs;45}46prim_unary_values(lhs, |x| x + rhs)47}4849fn prim_wrapping_sub_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {50if rhs == 0.0 {51return lhs;52}53Self::prim_wrapping_add_scalar(lhs, -rhs)54}5556fn prim_wrapping_sub_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<$T> {57if lhs == 0.0 {58Self::prim_wrapping_neg(rhs)59} else {60prim_unary_values(rhs, |x| lhs - x)61}62}6364fn prim_wrapping_mul_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {65// No optimization for multiplication by zero, would invalidate NaNs/infinities.66if rhs == 1.0 {67lhs68} else if rhs == -1.0 {69Self::prim_wrapping_neg(lhs)70} else {71prim_unary_values(lhs, |x| x * rhs)72}73}7475fn prim_wrapping_floor_div_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {76let inv = 1.0 / rhs;77prim_unary_values(lhs, |x| (x * inv).floor())78}7980fn prim_wrapping_floor_div_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<$T> {81prim_unary_values(rhs, |x| (lhs / x).floor())82}8384fn prim_wrapping_trunc_div_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {85let inv = 1.0 / rhs;86prim_unary_values(lhs, |x| (x * inv).trunc())87}8889fn prim_wrapping_trunc_div_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<$T> {90prim_unary_values(rhs, |x| (lhs / x).trunc())91}9293fn prim_wrapping_mod_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {94let inv = 1.0 / rhs;95prim_unary_values(lhs, |x| x - rhs * (x * inv).floor())96}9798fn prim_wrapping_mod_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<$T> {99prim_unary_values(rhs, |x| lhs - x * (lhs / x).floor())100}101102fn prim_checked_mul_scalar(_lhs: PArr<$T>, _rhs: $T) -> PArr<$T> {103unimplemented!()104}105106fn prim_true_div(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<Self::TrueDivT> {107prim_binary_values(lhs, rhs, |l, r| l / r)108}109110fn prim_true_div_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<Self::TrueDivT> {111Self::prim_wrapping_mul_scalar(lhs, 1.0 / rhs)112}113114fn prim_true_div_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<Self::TrueDivT> {115prim_unary_values(rhs, |x| lhs / x)116}117}118};119}120121impl_float_arith_kernel!(f32);122impl_float_arith_kernel!(f64);123124125