Whatsonyourmind commented on issue #9422:
URL: https://github.com/apache/arrow-rs/issues/9422#issuecomment-4182733753
The fix needs to implement half-up rounding (banker's rounding or
round-half-to-even would also be defensible, but Postgres and DuckDB both use
half-up).
The core logic: when parsing a decimal string with more fractional digits
than the target scale allows, you need to look at the first truncated digit to
decide whether to round up.
```rust
// After parsing the significant digits and determining where truncation
occurs:
fn round_decimal_parse(digits: &[u8], truncation_point: usize, scale: i8) ->
i128 {
let mut result = parse_digits_up_to(digits, truncation_point);
if truncation_point < digits.len() {
let next_digit = digits[truncation_point] - b'0';
if next_digit >= 5 {
// Round away from zero (half-up for positive, half-down for
negative)
if result >= 0 {
result += 1;
} else {
result -= 1;
}
}
}
result
}
```
For the specific case of scale=0, parsing "1.9" should give:
1. Parse integer part: 1
2. First truncated fractional digit: 9 >= 5, so round up
3. Result: 2
One edge case to watch: rounding can cause overflow. Parsing "99.5" as
`numeric(2, 0)` should round to 100, which exceeds the precision. Postgres
raises an error here. The implementation should check `result < 10^precision`
after rounding and return an overflow error if violated.
--
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]