Skip to content

DX-90291: Gandiva: fix round(double, scale) overflow for large values - #148

Merged
victor6567758 merged 2 commits into
dremio:dremio_27.0_23_19from
victor6567758:DX-90291-gandiva-round
Oct 17, 2026
Merged

victor6567758 merged 2 commits into
dremio:dremio_27.0_23_19from
victor6567758:DX-90291-gandiva-round

Conversation

@victor6567758

@victor6567758 victor6567758 commented Oct 15, 2026 •

Copy link
Copy Markdown

SUMMARY

round(double_field, 100) returned Infinity for large values.

Cause: round_float64_int32 and round_float32_int32 (ROUND_DECIMAL_TO_SCALE) multiplied the number by 10^scale before rounding. That overflowed to inf (or to NaN for a huge scale). For a large scale it also lost the last digit, for example round(451.65, 100) returned 451.65000000000003.

Fix: return the number unchanged when abs(number) >= 2^52 / 10^scale. The check runs before the multiplication, so nothing can overflow. At that magnitude the scaled value has no fractional part, so there is nothing to round. The negated comparison also returns NaN and ±inf unchanged. A huge positive scale such
as 400, where 10^scale is inf, returns the input too.

Note: if (!(fabs(number) < kMaxRoundableScaledValue / scale_multiplier)): Negated < so that NaN, for which every comparison is false, also takes the early return along with large values and ±inf.

Known limits (out of scope):

  • A hugely negative scale (multiplier 0) still gives NaN.
  • Within about one ulp of abs(number * 10^scal) ≈ 2^52, the multiply-round-divide approach can be one ulp off at ties. The old code did the same, so this is not a regression.

TEST

Tests: new assertions in TestExtendedMathOps.TestRoundDecimal (large values, their negatives, and a last-digit case at scale 100).

SELECT double_field,round(double_field,3),round(double_field,4),round(double_field,7),round(double_field,10),round(double_field,100),round(double_field,8),round(double_field,-100) FROM gandiva_functions."numbers.parquet" where double_field != 0 is attached to the story: https://dremio.atlassian.net/browse/DX-90291?issueKey=DX-90291

@alinaliBQ alinaliBQ left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall lgtm

Comment thread cpp/src/gandiva/precompiled/extended_math_ops_test.cc
@victor6567758
victor6567758 force-pushed the DX-90291-gandiva-round branch from a097c4f to 4cbf105 Compare October 16, 2026 17:36
@victor6567758
victor6567758 marked this pull request as ready for review October 16, 2026 17:40
Comment thread cpp/src/gandiva/precompiled/extended_math_ops.cc Outdated
lriggs
lriggs previously approved these changes Oct 16, 2026

@lriggs lriggs left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Learned something new:

Ulp: unit in the last place or unit of least precision (ulp) is the spacing between two consecutive floating-point numbers, i.e., the value the least significant digit (rightmost digit) represents if it is 1. It is used as a measure of accuracy in numeric calculations.

@victor6567758

Copy link
Copy Markdown
Author

@alinaliBQ @lriggs please review after suggested fixes.

Comment thread cpp/src/gandiva/precompiled/extended_math_ops.cc
Comment thread cpp/src/gandiva/precompiled/extended_math_ops_test.cc Outdated
@lriggs

lriggs commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator

Also consider creating a GH issue in apache/arrow and making this fix upstream as well.

@victor6567758
victor6567758 merged commit f54c22e into dremio:dremio_27.0_23_19 Oct 17, 2026
20 of 40 checks passed
lriggs pushed a commit that referenced this pull request Oct 20, 2026
…#148)

* DX-90291: Gandiva: fix round(double, scale) overflow for large values

* DX-90291: Rename round limit constant, document float32 use
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants