Path: blob/main/crates/polars-compute/src/arithmetic/float.rs
8406 views
use arrow::array::PrimitiveArray as PArr;1use num_traits::{One, Zero};2use polars_utils::float16::pf16;34use super::PrimitiveArithmeticKernelImpl;5use crate::arity::{prim_binary_values, prim_unary_values};67macro_rules! impl_float_arith_kernel {8($T:ty) => {9impl PrimitiveArithmeticKernelImpl for $T {10type TrueDivT = $T;1112fn prim_wrapping_abs(lhs: PArr<$T>) -> PArr<$T> {13prim_unary_values(lhs, |x| x.abs())14}1516fn prim_wrapping_neg(lhs: PArr<$T>) -> PArr<$T> {17prim_unary_values(lhs, |x| -x)18}1920fn prim_wrapping_add(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {21prim_binary_values(lhs, rhs, |l, r| l + r)22}2324fn prim_wrapping_sub(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {25prim_binary_values(lhs, rhs, |l, r| l - r)26}2728fn prim_wrapping_mul(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {29prim_binary_values(lhs, rhs, |l, r| l * r)30}3132fn prim_wrapping_floor_div(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {33prim_binary_values(lhs, rhs, |l, r| (l / r).floor())34}3536fn prim_wrapping_trunc_div(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {37prim_binary_values(lhs, rhs, |l, r| (l / r).trunc())38}3940fn prim_wrapping_mod(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {41prim_binary_values(lhs, rhs, |l, r| l - r * (l / r).floor())42}4344fn prim_wrapping_add_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {45if rhs == <$T>::zero() {46return lhs;47}48prim_unary_values(lhs, |x| x + rhs)49}5051fn prim_wrapping_sub_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {52if rhs == <$T>::zero() {53return lhs;54}55Self::prim_wrapping_add_scalar(lhs, -rhs)56}5758fn prim_wrapping_sub_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<$T> {59if lhs == <$T>::zero() {60Self::prim_wrapping_neg(rhs)61} else {62prim_unary_values(rhs, |x| lhs - x)63}64}6566fn prim_wrapping_mul_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {67// No optimization for multiplication by zero, would invalidate NaNs/infinities.68if rhs == <$T>::one() {69lhs70} else if rhs == -<$T>::one() {71Self::prim_wrapping_neg(lhs)72} else {73prim_unary_values(lhs, |x| x * rhs)74}75}7677fn prim_wrapping_floor_div_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {78let inv = <$T>::one() / rhs;79prim_unary_values(lhs, |x| (x * inv).floor())80}8182fn prim_wrapping_floor_div_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<$T> {83prim_unary_values(rhs, |x| (lhs / x).floor())84}8586fn prim_wrapping_trunc_div_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {87let inv = <$T>::one() / rhs;88prim_unary_values(lhs, |x| (x * inv).trunc())89}9091fn prim_wrapping_trunc_div_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<$T> {92prim_unary_values(rhs, |x| (lhs / x).trunc())93}9495fn prim_wrapping_mod_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {96let inv = <$T>::one() / rhs;97prim_unary_values(lhs, |x| x - rhs * (x * inv).floor())98}99100fn prim_wrapping_mod_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<$T> {101prim_unary_values(rhs, |x| lhs - x * (lhs / x).floor())102}103104fn prim_checked_mul_scalar(_lhs: PArr<$T>, _rhs: $T) -> PArr<$T> {105unimplemented!()106}107108fn prim_true_div(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<Self::TrueDivT> {109prim_binary_values(lhs, rhs, |l, r| l / r)110}111112fn prim_true_div_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<Self::TrueDivT> {113Self::prim_wrapping_mul_scalar(lhs, <$T>::one() / rhs)114}115116fn prim_true_div_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<Self::TrueDivT> {117prim_unary_values(rhs, |x| lhs / x)118}119}120};121}122123impl_float_arith_kernel!(pf16);124impl_float_arith_kernel!(f32);125impl_float_arith_kernel!(f64);126127128