pub fn adaptive_div(
    lhs: &PrimitiveArray<i128>,
    rhs: &PrimitiveArray<i128>,
) -> Result<PrimitiveArray<i128>> {
    check_same_len(lhs, rhs)?;

    if let (DataType::Decimal(lhs_p, lhs_s), DataType::Decimal(rhs_p, rhs_s)) =
        (lhs.data_type(), rhs.data_type())
    {
        // The resulting precision is mutable because it could change while
        // looping through the iterator
        let (mut res_p, res_s, diff) = adjusted_precision_scale(*lhs_p, *lhs_s, *rhs_p, *rhs_s);

        let shift = 10i128.pow(diff as u32);
        let shift_1 = 10i128.pow(res_s as u32);
        let mut max = max_value(res_p);

        let iter = lhs.values().iter().zip(rhs.values().iter()).map(|(l, r)| {
            let numeral: i128 = l * shift_1;

            // Based on the array's scales one of the arguments in the sum has to be shifted
            // to the left to match the final scale
            let res = if lhs_s > rhs_s {
                numeral.checked_div(r * shift)
            } else {
                (numeral * shift).checked_div(*r)
            }
            .expect("Found division by zero");

            // The precision of the resulting array will change if one of the
            // multiplications during the iteration produces a value bigger
            // than the possible value for the initial precision

            //  10.0000 -> 6, 4
            //  00.1000 -> 6, 4
            // -----------------
            // 100.0000 -> 7, 4
            if res.abs() > max {
                res_p = number_digits(res);
                max = max_value(res_p);
            }

            res
        });
        let values = Buffer::from_trusted_len_iter(iter);

        let validity = combine_validities(lhs.validity(), rhs.validity());

        Ok(PrimitiveArray::<i128>::from_data(
            DataType::Decimal(res_p, res_s),
            values,
            validity,
        ))
    } else {
        Err(ArrowError::InvalidArgumentError(
            "Incorrect data type for the array".to_string(),
        ))
    }
}
/// Adaptive division of two decimal primitive arrays with different precision
/// and scale. If the precision and scale is different, then the smallest scale
/// and precision is adjusted to the largest precision and scale. If during the
/// division one of the results is larger than the max possible value, the
/// result precision is changed to the precision of the max value. The function
/// panics when divided by zero.
///
/// ```nocode
///  1000.00   -> 7, 2
///    10.0000 -> 6, 4
/// -----------------
///   100.0000 -> 9, 4
/// ```
/// # Examples
/// ```
/// use arrow2::compute::arithmetics::decimal::adaptive_div;
/// use arrow2::array::PrimitiveArray;
/// use arrow2::datatypes::DataType;
///
/// let a = PrimitiveArray::from([Some(1000_00i128)]).to(DataType::Decimal(7, 2));
/// let b = PrimitiveArray::from([Some(10_0000i128)]).to(DataType::Decimal(6, 4));
/// let result = adaptive_div(&a, &b).unwrap();
/// let expected = PrimitiveArray::from([Some(100_0000i128)]).to(DataType::Decimal(9, 4));
///
/// assert_eq!(result, expected);
/// ```
Adaptive division of two decimal primitive arrays with different precision
and scale. If the precision and scale is different, then the smallest scale
and precision is adjusted to the largest precision and scale. If during the
division one of the results is larger than the max possible value, the
result precision is changed to the precision of the max value. The function
panics when divided by zero.




Adaptive division of two decimal primitive arrays with different precision and scale . If the precision and scale is different then the smallest scale and precision is adjusted to the largest precision and scale . If during the division one of the results is larger than the max possible value the result precision is changed to the precision of the max value . The function panics when divided by zero .
pub fn adaptive_div(
    lhs: &PrimitiveArray<i128>,
    rhs: &PrimitiveArray<i128>,
) -> Result<PrimitiveArray<i128>> {
    check_same_len(lhs, rhs)?;
    if let (DataType::Decimal(lhs_p, lhs_s), DataType::Decimal(rhs_p, rhs_s)) =
        (lhs.data_type(), rhs.data_type())
    {
        // The resulting precision is mutable because it could change while
        // looping through the iterator
        let (mut res_p, res_s, diff) = adjusted_precision_scale(*lhs_p, *lhs_s, *rhs_p, *rhs_s);
        let shift = 10i128.pow(diff as u32);
        let shift_1 = 10i128.pow(res_s as u32);
        let mut max = max_value(res_p);
        let iter = lhs.values().iter().zip(rhs.values().iter()).map(|(l, r)| {
            let numeral: i128 = l * shift_1;
            // Based on the array's scales one of the arguments in the sum has to be shifted
            // to the left to match the final scale
            let res = if lhs_s > rhs_s {
                numeral.checked_div(r * shift)
            } else {
                (numeral * shift).checked_div(*r)
            }
            .expect("Found division by zero");
            // The precision of the resulting array will change if one of the
            // multiplications during the iteration produces a value bigger
            // than the possible value for the initial precision
            //  10.0000 -> 6, 4
            //  00.1000 -> 6, 4
            // -----------------
            // 100.0000 -> 7, 4
            if res.abs() > max {
                res_p = number_digits(res);
                max = max_value(res_p);
            }
            res
        });
        let values = Buffer::from_trusted_len_iter(iter);
        let validity = combine_validities(lhs.validity(), rhs.validity());
        Ok(PrimitiveArray::<i128>::from_data(
            DataType::Decimal(res_p, res_s),
            values,
            validity,
        ))
    } else {
        Err(ArrowError::InvalidArgumentError(
            "Incorrect data type for the array".to_string(),
        ))
    }
}
pub fn adaptive_div ( lhs : & PrimitiveArray < i128 > , rhs : & PrimitiveArray < i128 > , ) -> Result < PrimitiveArray < i128 > > { check_same_len ( lhs , rhs ) ? ; if let ( DataType :: Decimal ( lhs_p , lhs_s ) , DataType :: Decimal ( rhs_p , rhs_s ) ) = ( lhs . data_type ( ) , rhs . data_type ( ) ) { // The resulting precision is mutable because it could change while // looping through the iterator let ( mut res_p , res_s , diff ) = adjusted_precision_scale ( * lhs_p , * lhs_s , * rhs_p , * rhs_s ) ; let shift = 10i128 . pow ( diff as u32 ) ; let shift_1 = 10i128 . pow ( res_s as u32 ) ; let mut max = max_value ( res_p ) ; let iter = lhs . values ( ) . iter ( ) . zip ( rhs . values ( ) . iter ( ) ) . map ( | ( l , r ) | { let numeral : i128 = l * shift_1 ; // Based on the array's scales one of the arguments in the sum has to be shifted // to the left to match the final scale let res = if lhs_s > rhs_s { numeral . checked_div ( r * shift ) } else { ( numeral * shift ) . checked_div ( * r ) } . expect ( " " ) ; // The precision of the resulting array will change if one of the // multiplications during the iteration produces a value bigger // than the possible value for the initial precision //  10.0000 -> 6, 4 //  00.1000 -> 6, 4 // ----------------- // 100.0000 -> 7, 4 if res . abs ( ) > max { res_p = number_digits ( res ) ; max = max_value ( res_p ) ; } res } ) ; let values = Buffer :: from_trusted_len_iter ( iter ) ; let validity = combine_validities ( lhs . validity ( ) , rhs . validity ( ) ) ; Ok ( PrimitiveArray :: < i128 > :: from_data ( DataType :: Decimal ( res_p , res_s ) , values , validity , ) ) } else { Err ( ArrowError :: InvalidArgumentError ( " " . to_string ( ) , ) ) } }
Adaptive division of two decimal primitive arrays with different precision
and scale.
Adaptive division of two decimal primitive arrays with different precision and scale .
lhs
&PrimitiveArray<i128>
rhs
&PrimitiveArray<i128>
lhs
&PrimitiveArray<i128>
rhs
&PrimitiveArray<i128>
examples
```
use arrow2::compute::arithmetics::decimal::adaptive_div;
use arrow2::array::PrimitiveArray;
use arrow2::datatypes::DataType.



assert_eq!(result, expected);
```
` ` ` use arrow2 :: compute :: arithmetics :: decimal :: adaptive_div ; use arrow2 :: array :: PrimitiveArray ; use arrow2 :: datatypes :: DataType . assert_eq! ( result expected ) ; ` ` `