diff options
author | Kenta Murata <mrkn@mrkn.jp> | 2021-01-15 10:04:48 +0900 |
---|---|---|
committer | Kenta Murata <mrkn@mrkn.jp> | 2021-01-16 00:08:09 +0900 |
commit | 9d0c5e2754c72936d604405152aebc149675a2e6 (patch) | |
tree | 217cd86bdda78c6e104303f5e6c6af6c4822b151 /ext/bigdecimal/bigdecimal.c | |
parent | f95f85b215d85dfd2c439d1a366bb6419274c7ac (diff) |
[ruby/bigdecimal] Use pre-allocated special values in BigDecimal_DoDivmod
https://github.com/ruby/bigdecimal/commit/d2746121cf
Diffstat (limited to 'ext/bigdecimal/bigdecimal.c')
-rw-r--r-- | ext/bigdecimal/bigdecimal.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index c93ad91e8c..8c79450660 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; } |