pub fn adaptive_sub(
    lhs: &PrimitiveArray<i128>,
    rhs: &PrimitiveArray<i128>,
) -> Result<PrimitiveArray<i128>> {
    // Checking if both arrays have the same length
    if lhs.len() != rhs.len() {
        return Err(ArrowError::InvalidArgumentError(
            "Arrays must have the same length".to_string(),
        ));
    }

    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 mut result = Vec::new();
        for (l, r) in lhs.values().iter().zip(rhs.values().iter()) {
            // 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: i128 = if lhs_s > rhs_s {
                l - r * 10i128.pow(diff as u32)
            } else {
                l * 10i128.pow(diff as u32) - r
            };

            // The precision of the resulting array will change if one of the
            // subtraction 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_value(res_p) {
                res_p = number_digits(res);
            }

            result.push(res);
        }

        let validity = combine_validities(lhs.validity(), rhs.validity());
        let values = Buffer::from(result);

        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 subtract 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 smaller than the min possible value, the
/// result precision is changed to the precision of the min value
///
/// ```nocode
///  99.9999 -> 6, 4
/// -00.0001 -> 6, 4
/// -----------------
/// 100.0000 -> 7, 4
/// ```
/// # Examples
/// ```
/// use arrow2::compute::arithmetics::decimal::sub::adaptive_sub;
/// use arrow2::array::PrimitiveArray;
/// use arrow2::datatypes::DataType;
///
/// let a = PrimitiveArray::from(&vec![Some(99_9999i128)]).to(DataType::Decimal(6, 4));
/// let b = PrimitiveArray::from(&vec![Some(-00_0001i128)]).to(DataType::Decimal(6, 4));
/// let result = adaptive_sub(&a, &b).unwrap();
/// let expected = PrimitiveArray::from(&vec![Some(100_0000i128)]).to(DataType::Decimal(7, 4));
///
/// assert_eq!(result, expected);
/// ```
Adaptive subtract 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 smaller than the min possible value, the
result precision is changed to the precision of the min value




Adaptive subtract 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 smaller than the min possible value the result precision is changed to the precision of the min value
pub fn adaptive_sub(
    lhs: &PrimitiveArray<i128>,
    rhs: &PrimitiveArray<i128>,
) -> Result<PrimitiveArray<i128>> {
    // Checking if both arrays have the same length
    if lhs.len() != rhs.len() {
        return Err(ArrowError::InvalidArgumentError(
            "Arrays must have the same length".to_string(),
        ));
    }
    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 mut result = Vec::new();
        for (l, r) in lhs.values().iter().zip(rhs.values().iter()) {
            // 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: i128 = if lhs_s > rhs_s {
                l - r * 10i128.pow(diff as u32)
            } else {
                l * 10i128.pow(diff as u32) - r
            };
            // The precision of the resulting array will change if one of the
            // subtraction 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_value(res_p) {
                res_p = number_digits(res);
            }
            result.push(res);
        }
        let validity = combine_validities(lhs.validity(), rhs.validity());
        let values = Buffer::from(result);
        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_sub ( lhs : & PrimitiveArray < i128 > , rhs : & PrimitiveArray < i128 > , ) -> Result < PrimitiveArray < i128 > > { // Checking if both arrays have the same length if lhs . len ( ) != rhs . len ( ) { return Err ( ArrowError :: InvalidArgumentError ( " " . to_string ( ) , ) ) ; } 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 mut result = Vec :: new ( ) ; for ( l , r ) in lhs . values ( ) . iter ( ) . zip ( rhs . values ( ) . iter ( ) ) { // 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 : i128 = if lhs_s > rhs_s { l - r * 10i128 . pow ( diff as u32 ) } else { l * 10i128 . pow ( diff as u32 ) - r } ; // The precision of the resulting array will change if one of the // subtraction 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_value ( res_p ) { res_p = number_digits ( res ) ; } result . push ( res ) ; } let validity = combine_validities ( lhs . validity ( ) , rhs . validity ( ) ) ; let values = Buffer :: from ( result ) ; Ok ( PrimitiveArray :: < i128 > :: from_data ( DataType :: Decimal ( res_p , res_s ) , values , validity , ) ) } else { Err ( ArrowError :: InvalidArgumentError ( " " . to_string ( ) , ) ) } }
Adaptive subtract of two decimal primitive arrays with different precision
and scale.
Adaptive subtract of two decimal primitive arrays with different precision and scale .
lhs
&PrimitiveArray<i128>
rhs
&PrimitiveArray<i128>
examples
```
use arrow2::compute::arithmetics::decimal::sub::adaptive_sub;
use arrow2::array::PrimitiveArray;
use arrow2::datatypes::DataType.



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