tustvold commented on code in PR #3139:
URL: https://github.com/apache/arrow-rs/pull/3139#discussion_r1028299154
##########
arrow-cast/src/cast.rs:
##########
@@ -1955,12 +1956,26 @@ fn cast_decimal_to_decimal_safe<const BYTE_WIDTH1:
usize, const BYTE_WIDTH2: usi
// For example, input_scale is 4 and output_scale is 3;
// Original value is 11234_i128, and will be cast to 1123_i128.
let div = 10_i128.pow((input_scale - output_scale) as u32);
+ let half = div / 2;
+ let neg_half = half.neg();
if BYTE_WIDTH1 == 16 {
let array =
array.as_any().downcast_ref::<Decimal128Array>().unwrap();
if BYTE_WIDTH2 == 16 {
- let iter = array
- .iter()
- .map(|v| v.and_then(|v| v.div_checked(div).ok()));
+ // rounding the result
+ let iter = array.iter().map(|v| {
+ v.map(|v| {
+ // the div must be gt_eq 10, we don't need to check
the overflow for the `div`/`mod` operation
+ let d = v / div;
+ let r = v % div;
Review Comment:
```suggestion
let d = v.wrapping_div(div);
let r = v.wrapping_rem(div);
```
##########
arrow-cast/src/cast.rs:
##########
@@ -1955,12 +1956,26 @@ fn cast_decimal_to_decimal_safe<const BYTE_WIDTH1:
usize, const BYTE_WIDTH2: usi
// For example, input_scale is 4 and output_scale is 3;
// Original value is 11234_i128, and will be cast to 1123_i128.
let div = 10_i128.pow((input_scale - output_scale) as u32);
+ let half = div / 2;
+ let neg_half = half.neg();
Review Comment:
```suggestion
let neg_half = half.wrapping_neg();
```
As we've divided by 2 this can't overflow
##########
arrow-cast/src/cast.rs:
##########
@@ -1955,12 +1956,26 @@ fn cast_decimal_to_decimal_safe<const BYTE_WIDTH1:
usize, const BYTE_WIDTH2: usi
// For example, input_scale is 4 and output_scale is 3;
// Original value is 11234_i128, and will be cast to 1123_i128.
let div = 10_i128.pow((input_scale - output_scale) as u32);
+ let half = div / 2;
+ let neg_half = half.neg();
if BYTE_WIDTH1 == 16 {
let array =
array.as_any().downcast_ref::<Decimal128Array>().unwrap();
if BYTE_WIDTH2 == 16 {
- let iter = array
- .iter()
- .map(|v| v.and_then(|v| v.div_checked(div).ok()));
+ // rounding the result
+ let iter = array.iter().map(|v| {
+ v.map(|v| {
+ // the div must be gt_eq 10, we don't need to check
the overflow for the `div`/`mod` operation
+ let d = v / div;
+ let r = v % div;
+ if v >= 0 && r >= half {
+ d + 1
Review Comment:
```suggestion
d.wrapping_add(1)
```
##########
arrow-cast/src/cast.rs:
##########
@@ -1955,12 +1956,26 @@ fn cast_decimal_to_decimal_safe<const BYTE_WIDTH1:
usize, const BYTE_WIDTH2: usi
// For example, input_scale is 4 and output_scale is 3;
// Original value is 11234_i128, and will be cast to 1123_i128.
let div = 10_i128.pow((input_scale - output_scale) as u32);
+ let half = div / 2;
+ let neg_half = half.neg();
if BYTE_WIDTH1 == 16 {
let array =
array.as_any().downcast_ref::<Decimal128Array>().unwrap();
if BYTE_WIDTH2 == 16 {
- let iter = array
- .iter()
- .map(|v| v.and_then(|v| v.div_checked(div).ok()));
+ // rounding the result
+ let iter = array.iter().map(|v| {
+ v.map(|v| {
+ // the div must be gt_eq 10, we don't need to check
the overflow for the `div`/`mod` operation
+ let d = v / div;
+ let r = v % div;
+ if v >= 0 && r >= half {
+ d + 1
+ } else if v < 0 && r <= neg_half {
+ d - 1
Review Comment:
```suggestion
d.wrapping_sub(1)
```
##########
arrow-cast/src/cast.rs:
##########
@@ -1981,9 +2006,23 @@ fn cast_decimal_to_decimal_safe<const BYTE_WIDTH1:
usize, const BYTE_WIDTH2: usi
} else {
let array =
array.as_any().downcast_ref::<Decimal256Array>().unwrap();
let div = i256::from_i128(div);
+ let half = div / i256::from_i128(2);
+ // TODO: it's better to implement the neg
+ let neg_half = half * i256::from_i128(-1);
Review Comment:
```suggestion
let neg_half = half.wrapping_neg();
```
--
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]