From 54a722bd42a1135e4ee064137ffeac86a7784328 Mon Sep 17 00:00:00 2001 From: matz Date: Wed, 10 Dec 2008 18:00:51 +0000 Subject: * math.c (domain_check): should not raise EDOM exception for NaN value if operand is also NaN. affects acos, asin, acosh, atanh, log, log2, log10, sqrt, gamma, lgamma. [ruby-dev:37357] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@20619 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- math.c | 75 ++++++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 32 deletions(-) (limited to 'math.c') diff --git a/math.c b/math.c index 2be2a6c51a..3ac543150b 100644 --- a/math.c +++ b/math.c @@ -35,13 +35,14 @@ to_flo(VALUE x) } while (0) static void -domain_check(double x, const char *msg) +domain_check(double x, double y, const char *msg) { while(1) { if (errno) { rb_sys_fail(msg); } - if (isnan(x)) { + if (isnan(y)) { + if (isnan(x)) break; #if defined(EDOM) errno = EDOM; #elif defined(ERANGE) @@ -146,12 +147,13 @@ math_tan(VALUE obj, VALUE x) static VALUE math_acos(VALUE obj, VALUE x) { - double d; + double d0, d; Need_Float(x); errno = 0; - d = acos(RFLOAT_VALUE(x)); - domain_check(d, "acos"); + d0 = RFLOAT_VALUE(x); + d = acos(d0); + domain_check(d0, d, "acos"); return DBL2NUM(d); } @@ -165,12 +167,13 @@ math_acos(VALUE obj, VALUE x) static VALUE math_asin(VALUE obj, VALUE x) { - double d; + double d0, d; Need_Float(x); errno = 0; - d = asin(RFLOAT_VALUE(x)); - domain_check(d, "asin"); + d0 = RFLOAT_VALUE(x); + d = asin(d0); + domain_check(d0, d, "asin"); return DBL2NUM(d); } @@ -267,12 +270,13 @@ math_tanh(VALUE obj, VALUE x) static VALUE math_acosh(VALUE obj, VALUE x) { - double d; + double d0, d; Need_Float(x); errno = 0; - d = acosh(RFLOAT_VALUE(x)); - domain_check(d, "acosh"); + d0 = RFLOAT_VALUE(x); + d = acosh(d0); + domain_check(d0, d, "acosh"); return DBL2NUM(d); } @@ -300,12 +304,13 @@ math_asinh(VALUE obj, VALUE x) static VALUE math_atanh(VALUE obj, VALUE x) { - double d; + double d0, d; Need_Float(x); errno = 0; - d = atanh(RFLOAT_VALUE(x)); - domain_check(d, "atanh"); + d0 = RFLOAT_VALUE(x); + d = atanh(d0); + domain_check(d0, d, "atanh"); infinity_check(x, d, "atanh"); return DBL2NUM(d); } @@ -347,17 +352,18 @@ static VALUE math_log(int argc, VALUE *argv) { VALUE x, base; - double d; + double d0, d; rb_scan_args(argc, argv, "11", &x, &base); Need_Float(x); errno = 0; - d = log(RFLOAT_VALUE(x)); + d0 = RFLOAT_VALUE(x); + d = log(d0); if (argc == 2) { Need_Float(base); d /= log(RFLOAT_VALUE(base)); } - domain_check(d, "log"); + domain_check(d0, d, "log"); infinity_check(x, d, "log"); return DBL2NUM(d); } @@ -384,12 +390,13 @@ extern double log2(double); static VALUE math_log2(VALUE obj, VALUE x) { - double d; + double d0, d; Need_Float(x); errno = 0; - d = log2(RFLOAT_VALUE(x)); - domain_check(d, "log2"); + d0 = RFLOAT_VALUE(x); + d = log2(d0); + domain_check(d0, d, "log2"); infinity_check(x, d, "log2"); return DBL2NUM(d); } @@ -404,12 +411,13 @@ math_log2(VALUE obj, VALUE x) static VALUE math_log10(VALUE obj, VALUE x) { - double d; + double d0, d; Need_Float(x); errno = 0; - d = log10(RFLOAT_VALUE(x)); - domain_check(d, "log10"); + d0 = RFLOAT_VALUE(x); + d = log10(d0); + domain_check(d0, d, "log10"); infinity_check(x, d, "log10"); return DBL2NUM(d); } @@ -441,12 +449,13 @@ math_log10(VALUE obj, VALUE x) static VALUE math_sqrt(VALUE obj, VALUE x) { - double d; + double d0, d; Need_Float(x); errno = 0; - d = sqrt(RFLOAT_VALUE(x)); - domain_check(d, "sqrt"); + d0 = RFLOAT_VALUE(x); + d = sqrt(d0); + domain_check(d0, d, "sqrt"); return DBL2NUM(d); } @@ -619,11 +628,12 @@ math_erfc(VALUE obj, VALUE x) static VALUE math_gamma(VALUE obj, VALUE x) { - double d; + double d0, d; Need_Float(x); errno = 0; - d = tgamma(RFLOAT_VALUE(x)); - domain_check(d, "gamma"); + d0 = RFLOAT_VALUE(x); + d = tgamma(d0); + domain_check(d0, d, "gamma"); return DBL2NUM(d); } @@ -642,13 +652,14 @@ math_gamma(VALUE obj, VALUE x) static VALUE math_lgamma(VALUE obj, VALUE x) { - double d; + double d0, d; int sign; VALUE v; Need_Float(x); errno = 0; - d = lgamma_r(RFLOAT_VALUE(x), &sign); - domain_check(d, "lgamma"); + d0 = RFLOAT_VALUE(x); + d = lgamma_r(d0, &sign); + domain_check(d0, d, "lgamma"); v = DBL2NUM(d); return rb_assoc_new(v, INT2FIX(sign)); } -- cgit v1.2.3