From 9d0c5e2754c72936d604405152aebc149675a2e6 Mon Sep 17 00:00:00 2001 From: Kenta Murata Date: Fri, 15 Jan 2021 10:04:48 +0900 Subject: [ruby/bigdecimal] Use pre-allocated special values in BigDecimal_DoDivmod https://github.com/ruby/bigdecimal/commit/d2746121cf --- ext/bigdecimal/bigdecimal.c | 47 +++++++++++++++++++++++++-------------------- 1 file 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; } -- cgit v1.2.3