mingmwang commented on issue #6278:
URL:
https://github.com/apache/arrow-datafusion/issues/6278#issuecomment-1540004152
@viirya @alamb
I think the major problem is that the `i256` math operation is not
efficient.
And the logic in the method `multiply_fixed_point()` in arrow-rs is not
consistent.
If required_scale == product_scale, it still use i128 for multiply(can still
overflow)
if product_scale > required_scale, use i256 for multiply and div, why ??
```rust
pub fn multiply_fixed_point(
left: &PrimitiveArray<Decimal128Type>,
right: &PrimitiveArray<Decimal128Type>,
required_scale: i8,
) -> Result<PrimitiveArray<Decimal128Type>, ArrowError> {
let product_scale = left.scale() + right.scale();
let precision = min(
left.precision() + right.precision() + 1,
DECIMAL128_MAX_PRECISION,
);
if required_scale == product_scale {
return multiply(left, right)?
.with_precision_and_scale(precision, required_scale);
}
if required_scale > product_scale {
return Err(ArrowError::ComputeError(format!(
"Required scale {} is greater than product scale {}",
required_scale, product_scale
)));
}
let divisor =
i256::from_i128(10).pow_wrapping((product_scale - required_scale) as
u32);
binary::<_, _, _, Decimal128Type>(left, right, |a, b| {
let a = i256::from_i128(a);
let b = i256::from_i128(b);
let mut mul = a.wrapping_mul(b);
mul = divide_and_round::<Decimal256Type>(mul, divisor);
mul.as_i128()
})
.and_then(|a| a.with_precision_and_scale(precision, required_scale))
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]