summaryrefslogtreecommitdiff
path: root/ext/bigdecimal
diff options
context:
space:
mode:
authorKenta Murata <mrkn@mrkn.jp>2021-01-15 10:04:48 +0900
committerKenta Murata <mrkn@mrkn.jp>2021-01-16 00:08:09 +0900
commit9d0c5e2754c72936d604405152aebc149675a2e6 (patch)
tree217cd86bdda78c6e104303f5e6c6af6c4822b151 /ext/bigdecimal
parentf95f85b215d85dfd2c439d1a366bb6419274c7ac (diff)
[ruby/bigdecimal] Use pre-allocated special values in BigDecimal_DoDivmod
https://github.com/ruby/bigdecimal/commit/d2746121cf
Diffstat (limited to 'ext/bigdecimal')
-rw-r--r--ext/bigdecimal/bigdecimal.c47
1 files changed, 26 insertions, 21 deletions
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index c93ad91..8c79450 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -1450,28 +1450,32 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod)
if (VpIsNaN(a) || VpIsNaN(b)) goto NaN;
if (VpIsInf(a) && VpIsInf(b)) goto NaN;
if (VpIsZero(b)) {
- rb_raise(rb_eZeroDivError, "divided by 0");
+ rb_raise(rb_eZeroDivError, "divided by 0");
}
if (VpIsInf(a)) {
- GUARD_OBJ(d, VpCreateRbObject(1, "0", true));
- VpSetInf(d, (SIGNED_VALUE)(VpGetSign(a) == VpGetSign(b) ? 1 : -1));
- GUARD_OBJ(c, VpCreateRbObject(1, "NaN", true));
- *div = d;
- *mod = c;
- return Qtrue;
+ if (VpGetSign(a) == VpGetSign(b)) {
+ VALUE inf = BigDecimal_positive_infinity();
+ TypedData_Get_Struct(inf, Real, &BigDecimal_data_type, *div);
+ }
+ else {
+ VALUE inf = BigDecimal_negative_infinity();
+ TypedData_Get_Struct(inf, Real, &BigDecimal_data_type, *div);
+ }
+ VALUE nan = BigDecimal_nan();
+ TypedData_Get_Struct(nan, Real, &BigDecimal_data_type, *mod);
+ return Qtrue;
}
if (VpIsInf(b)) {
- GUARD_OBJ(d, VpCreateRbObject(1, "0", true));
- *div = d;
- *mod = a;
- return Qtrue;
+ VALUE zero = BigDecimal_positive_zero();
+ TypedData_Get_Struct(zero, Real, &BigDecimal_data_type, *div);
+ *mod = a;
+ return Qtrue;
}
if (VpIsZero(a)) {
- GUARD_OBJ(c, VpCreateRbObject(1, "0", true));
- GUARD_OBJ(d, VpCreateRbObject(1, "0", true));
- *div = d;
- *mod = c;
- return Qtrue;
+ VALUE zero = BigDecimal_positive_zero();
+ TypedData_Get_Struct(zero, Real, &BigDecimal_data_type, *div);
+ TypedData_Get_Struct(zero, Real, &BigDecimal_data_type, *mod);
+ return Qtrue;
}
mx = a->Prec + vabs(a->exponent);
@@ -1497,11 +1501,12 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod)
}
return Qtrue;
-NaN:
- GUARD_OBJ(c, VpCreateRbObject(1, "NaN", true));
- GUARD_OBJ(d, VpCreateRbObject(1, "NaN", true));
- *div = d;
- *mod = c;
+ NaN:
+ {
+ VALUE nan = BigDecimal_nan();
+ TypedData_Get_Struct(nan, Real, &BigDecimal_data_type, *div);
+ TypedData_Get_Struct(nan, Real, &BigDecimal_data_type, *mod);
+ }
return Qtrue;
}