summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorKenta Murata <mrkn@mrkn.jp>2021-12-24 00:26:34 +0900
committerKenta Murata <mrkn@mrkn.jp>2021-12-24 02:29:01 +0900
commita1d9fbef05fbf507b4c68cf3fbc50c6e27a3293e (patch)
tree3a3c4aa93c8a222f782d0ff70e17bf771aaea838 /ext
parent680a4ebb3ce7a3028b897204c2f0d3a546194eb8 (diff)
[ruby/bigdecimal] Fix the result precision of BigDecimal#divmod
https://github.com/ruby/bigdecimal/commit/a32f6cb9e2
Diffstat (limited to 'ext')
-rw-r--r--ext/bigdecimal/bigdecimal.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index 5af6c7c5ba..4111fbd7d3 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -1618,7 +1618,8 @@ BigDecimal_divide(VALUE self, VALUE r, Real **c, Real **res, Real **div)
/* For c = self.div(r): with round operation */
{
ENTER(5);
- Real *a, *b;
+ Real *a, *b, *d;
+ ssize_t a_prec, b_prec;
size_t mx;
TypedData_Get_Struct(self, Real, &BigDecimal_data_type, a);
@@ -1644,18 +1645,27 @@ BigDecimal_divide(VALUE self, VALUE r, Real **c, Real **res, Real **div)
TypedData_Get_Struct(rr, Real, &BigDecimal_data_type, b);
SAVE(b);
-
*div = b;
+
mx = (a->Prec > b->Prec) ? a->Prec : b->Prec;
mx *= BASE_FIG;
+
+ BigDecimal_count_precision_and_scale(self, &a_prec, NULL);
+ BigDecimal_count_precision_and_scale(rr, &b_prec, NULL);
+ mx = (a_prec > b_prec) ? a_prec : b_prec;
+
if (2*BIGDECIMAL_DOUBLE_FIGURES > mx)
mx = 2*BIGDECIMAL_DOUBLE_FIGURES;
+
GUARD_OBJ((*c), VpCreateRbObject(mx + 2*BASE_FIG, "#0", true));
GUARD_OBJ((*res), VpCreateRbObject(mx*2 + 2*BASE_FIG, "#0", true));
VpDivd(*c, *res, a, b);
+
return Qnil;
}
+static VALUE BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod);
+
/* call-seq:
* a / b -> bigdecimal
*
@@ -1736,6 +1746,7 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod)
ENTER(8);
Real *c=NULL, *d=NULL, *res=NULL;
Real *a, *b;
+ ssize_t a_prec, b_prec;
size_t mx;
TypedData_Get_Struct(self, Real, &BigDecimal_data_type, a);
@@ -1793,8 +1804,10 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod)
return Qtrue;
}
- mx = (a->Prec > b->Prec) ? a->Prec : b->Prec;
- mx *= BASE_FIG;
+ BigDecimal_count_precision_and_scale(self, &a_prec, NULL);
+ BigDecimal_count_precision_and_scale(rr, &b_prec, NULL);
+
+ mx = (a_prec > b_prec) ? a_prec : b_prec;
if (2*BIGDECIMAL_DOUBLE_FIGURES > mx)
mx = 2*BIGDECIMAL_DOUBLE_FIGURES;