pub fn adaptive_add(
    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 mut max = max_value(res_p);

        let iter = lhs.values().iter().zip(rhs.values().iter()).map(|(l, r)| {
            // 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 {
                l + r * shift
            } else {
                l * shift + r
            };

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

            //  99.9999 -> 6, 4
            //  00.0001 -> 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 addition 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
/// addition one of the results is larger than the max possible value, the
/// result precision is changed to the precision of the max value
///
/// ```nocode
/// 11111.11   -> 7, 2
/// 11111.111  -> 8, 3
/// ------------------
/// 22222.221  -> 8, 3
/// ```
/// # Examples
/// ```
/// use arrow2::compute::arithmetics::decimal::adaptive_add;
/// use arrow2::array::PrimitiveArray;
/// use arrow2::datatypes::DataType;
///
/// let a = PrimitiveArray::from([Some(11111_11i128)]).to(DataType::Decimal(7, 2));
/// let b = PrimitiveArray::from([Some(11111_111i128)]).to(DataType::Decimal(8, 3));
/// let result = adaptive_add(&a, &b).unwrap();
/// let expected = PrimitiveArray::from([Some(22222_221i128)]).to(DataType::Decimal(8, 3));
///
/// assert_eq!(result, expected);
/// ```
Adaptive addition 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
addition one of the results is larger than the max possible value, the
result precision is changed to the precision of the max value




Adaptive addition 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 addition one of the results is larger than the max possible value the result precision is changed to the precision of the max value
pub fn adaptive_add(
    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 mut max = max_value(res_p);
        let iter = lhs.values().iter().zip(rhs.values().iter()).map(|(l, r)| {
            // 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 {
                l + r * shift
            } else {
                l * shift + r
            };
            // The precision of the resulting array will change if one of the
            // sums during the iteration produces a value bigger than the
            // possible value for the initial precision
            //  99.9999 -> 6, 4
            //  00.0001 -> 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_add ( 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 mut max = max_value ( res_p ) ; let iter = lhs . values ( ) . iter ( ) . zip ( rhs . values ( ) . iter ( ) ) . map ( | ( l , r ) | { // 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 { l + r * shift } else { l * shift + r } ; // The precision of the resulting array will change if one of the // sums during the iteration produces a value bigger than the // possible value for the initial precision //  99.9999 -> 6, 4 //  00.0001 -> 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 addition of two decimal primitive arrays with different precision
and scale.
Adaptive addition 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_add;
use arrow2::array::PrimitiveArray;
use arrow2::datatypes::DataType.



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