Skip to content

Allocate minimum necessary digits for quotient and remainder#326

Closed
tompng wants to merge 2 commits into
ruby:masterfrom
tompng:div_allocation_fix
Closed

Allocate minimum necessary digits for quotient and remainder#326
tompng wants to merge 2 commits into
ruby:masterfrom
tompng:div_allocation_fix

Conversation

@tompng

@tompng tompng commented May 24, 2025

Copy link
Copy Markdown
Member

Fixes #220 and #222
Fixes wrong calculation of quotient and remainder precision in a / b division.

Precision of quotient is sufficient enough with [a_prec,b_prec].max+extra.
Required remainder allocation size can be calculated from requirements of VpDivd.
VpDivd requires r_maxprec > a_prec and r_maxprec > b_prec+c_maxprec-2.

word_r = r->MaxPrec;

if (word_a >= word_r) goto space_error;
if (word_a >= word_r || word_b + word_c - 2 >= word_r) goto space_error;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

There are two more goto space_error in this function.
One is on L6218

ind_r = ind_c + ind_b;
if (ind_r >= word_r) goto space_error;

And another in L6253

ind_r = b->Prec + ind_c - 1; // L6242
ind_r = b->Prec + ind_c; // L6250 (ind_c + 1 < word_c is ensured in L6247)
if (ind_r >= word_r) goto space_error;

Both has the same requirement: (word_b-1) + (word_c-1) < word_r

@tompng tompng force-pushed the div_allocation_fix branch from 4ed8610 to 65922a8 Compare May 24, 2025 18:04
Comment on lines +1857 to 1860
mx = ((a_prec > b_prec) ? a_prec : b_prec) + BIGDECIMAL_DOUBLE_FIGURES;

if (2*BIGDECIMAL_DOUBLE_FIGURES > mx)
mx = 2*BIGDECIMAL_DOUBLE_FIGURES;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Precision was max(a_prec*2, b_prec*2, 32).
I think we normally need max(a_prec, b_prec) + extra precision, and the extra part was ≧16 before.

tompng added 2 commits May 25, 2025 12:33
Fixes wrong calculation of quotient and remainder precision in `a / b` division.
Precision of quotient is sufficient enough with `[a_prec,b_prec].max+extra`.
Required remainder allocation size can be calculated from requirements of VpDivd.
VpDivd requires `r_maxprec > a_prec` and `r_maxprec > b_prec+c_maxprec-2`.
@tompng tompng force-pushed the div_allocation_fix branch from 65922a8 to 952f481 Compare May 25, 2025 03:39
@tompng tompng marked this pull request as draft May 25, 2025 04:00
@tompng tompng marked this pull request as ready for review May 25, 2025 15:38
@tompng

tompng commented May 27, 2025

Copy link
Copy Markdown
Member Author

I think this is the right fix for #220 and #222.
But BigDecimal_div and BigDecimal_divide both have rounding problems #272 and #328.
Closing this because the right fix for rounding is to first integrate these two divisions, use the same logic and fix one single rounding problem.

@tompng tompng closed this May 27, 2025
@tompng tompng deleted the div_allocation_fix branch May 27, 2025 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"ERROR(VpDivd): space for remainder too small" for certain division

1 participant