* math.c (math_gamma): get rid of direct comparison between too

big double and integer, with gcc on x86_64.  [ruby-core:25257]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24738 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2009-09-02 07:50:16 +00:00
Родитель 274fa77e3f
Коммит 3fe5402dfa
3 изменённых файлов: 22 добавлений и 3 удалений

Просмотреть файл

@ -1,3 +1,8 @@
Wed Sep 2 16:49:53 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* math.c (math_gamma): get rid of direct comparison between too
big double and integer, with gcc on x86_64. [ruby-core:25257]
Wed Sep 2 13:47:30 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* math.c (domain_check): simplified.

9
math.c
Просмотреть файл

@ -13,6 +13,8 @@
#include <math.h>
#include <errno.h>
#define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
VALUE rb_mMath;
extern VALUE rb_to_float(VALUE val);
@ -663,13 +665,14 @@ math_gamma(VALUE obj, VALUE x)
};
double d0, d;
double intpart, fracpart;
int n;
Need_Float(x);
d0 = RFLOAT_VALUE(x);
fracpart = modf(d0, &intpart);
if (fracpart == 0.0 &&
0 < intpart &&
(size_t)intpart <= sizeof(fact_table)/sizeof(*fact_table)) {
return DBL2NUM(fact_table[(int)intpart - 1]);
0 < intpart &&
(n = (int)intpart - 1) < numberof(fact_table)) {
return DBL2NUM(fact_table[n]);
}
errno = 0;
d = tgamma(d0);

Просмотреть файл

@ -1,6 +1,10 @@
require 'test/unit'
class TestMath < Test::Unit::TestCase
def assert_infinity(a, *rest)
assert(!a.finite?, *rest)
end
def check(a, b)
err = [Float::EPSILON * 4, [a.abs, b.abs].max * Float::EPSILON * 256].max
assert_in_delta(a, b, err)
@ -189,6 +193,13 @@ class TestMath < Test::Unit::TestCase
check(2, Math.gamma(3))
check(15 * sqrt_pi / 8, Math.gamma(3.5))
check(6, Math.gamma(4))
# no SEGV [ruby-core:25257]
31.upto(65) do |i|
i = 1 << i
assert_infinity(Math.gamma(i))
assert_infinity(Math.gamma(i-1))
end
end
def test_lgamma