Skip to content

Commit 2d63079

Browse files
committed
Create a process to initialize bc_num of rem
1 parent 484d9df commit 2d63079

File tree

1 file changed

+42
-2
lines changed
  • ext/bcmath/libbcmath/src

1 file changed

+42
-2
lines changed

ext/bcmath/libbcmath/src/div.c

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,10 +413,12 @@ bool bc_divide_ex(bc_num numerator, bc_num divisor, bc_num *quot, bc_num *rem, s
413413
numerator_size -= numerator_leading_zeros;
414414

415415
/* check and remove divisor leading zeros */
416+
size_t divisor_leading_zeros = 0;
416417
while (*divisorptr == 0) {
417418
divisorptr++;
418-
divisor_size--;
419+
divisor_leading_zeros++;
419420
}
421+
divisor_size -= divisor_leading_zeros;
420422

421423
if (divisor_size > numerator_size) {
422424
goto quot_zero;
@@ -443,8 +445,46 @@ bool bc_divide_ex(bc_num numerator, bc_num divisor, bc_num *quot, bc_num *rem, s
443445
(*quot)->n_sign = numerator->n_sign == divisor->n_sign ? PLUS : MINUS;
444446
}
445447

448+
/**
449+
* If the calculation uses more digits than the scale of rem, writing the vector directly to rem
450+
* will exceed the size, so calculate the excess size in advance.
451+
*/
452+
size_t rem_over_size = 0;
453+
454+
/**
455+
* Conversely, there are cases where the vector does not fill the rem size.
456+
* In this case, the size to be written is calculated in advance to determine the start position for writing to rem.
457+
*/
458+
size_t rem_write_size = 0;
459+
460+
size_t rem_size = 0;
461+
size_t numerator_rem_len_diff = 0;
446462
if (use_rem) {
447-
/* TODO: create bc_num for rem */
463+
size_t divisor_int_size = divisor->n_len > divisor_leading_zeros ? divisor->n_len - divisor_leading_zeros : 0;
464+
size_t divisor_frac_size = divisor->n_scale > divisor_trailing_zeros ? divisor->n_scale - divisor_trailing_zeros : 0;
465+
rem_scale = MIN(MAX(numerator->n_scale, divisor_frac_size), rem_scale);
466+
467+
*rem = bc_new_num_nonzeroed(divisor_int_size > 0 ? divisor_int_size : 1, rem_scale); // 1 is for 0
468+
(*rem)->n_sign = numerator->n_sign;
469+
470+
if (divisor_frac_size > rem_scale) {
471+
rem_over_size = divisor_frac_size - rem_scale;
472+
rem_write_size = (*rem)->n_len + rem_scale;
473+
} else {
474+
if (divisor_frac_size > 0) {
475+
rem_write_size = (*rem)->n_len + divisor_frac_size;
476+
} else {
477+
/* e.g. 123 % 30 */
478+
rem_write_size = (*rem)->n_len - (divisor_trailing_zeros - divisor->n_scale);
479+
}
480+
}
481+
482+
rem_size = (*rem)->n_len + (*rem)->n_scale;
483+
if (rem_size > rem_write_size) {
484+
size_t copy_size = rem_size - rem_write_size;
485+
numerator_rem_len_diff = numerator->n_len - (*rem)->n_len;
486+
memcpy((*rem)->n_value + rem_write_size, numerator->n_value + rem_write_size + numerator_rem_len_diff, copy_size);
487+
}
448488
}
449489

450490
/* Size that can be read from numeratorptr */

0 commit comments

Comments
 (0)