Bug #2381
closedMath.gammaの挙動がx86_64とia64で異なる
Description
=begin
x86_64とia64でMath.gamma(4294967296) の結果などが異なる。
$ ./ruby -ve 'p Math.gamma(4294967296) '
ruby 1.9.2dev (2009-11-17 trunk 25805) [x86_64-linux]
Infinity
$ ./ruby -ve 'p Math.gamma(4294967296).finite? '
ruby 1.9.2dev (2009-11-17 trunk 25805) [x86_64-linux]
false
$ ./ruby -ve 'p Math.gamma(4294967296) '
ruby 1.9.2dev (2009-11-17 trunk 25805) [ia64-linux]
9.652349077525983e-315
$ ./ruby -ve 'p Math.gamma(4294967296).finite? '
ruby 1.9.2dev (2009-11-17 trunk 25805) [ia64-linux]
true
文字列表現に変換するときに finite? 相当のチェックをしている様子だが、これがうまく機能していない。
numeric.c:flo_is_finite_p, numeric.c:flo_to_s などでの挙動が異なる。
なお、 tgamma(3) を呼び出した単体の結果ではどちらも "inf" を返却している。
=end
Files
Updated by takano32 (Mitsuhiro TAKANO) over 14 years ago
- File math.c.diff math.c.diff added
=begin
math.cの671行目付近での 0 < intpart という条件式にて intpart が 0 よりも微妙に大きい double型であったため、意図した処理ではなくなったように思える。
該当部分のパッチを添付する。
=end
Updated by usa (Usaku NAKAMURA) over 14 years ago
=begin
こんにちは、なかむら(う)です。
In message "[ruby-dev:39710] [Bug #2381] Math.gammaの挙動がx86_64とia64で異なる"
on Nov.18,2009 11:30:57, redmine@ruby-lang.org wrote:
math.cの671行目付近での 0 < intpart という条件式にて intpart が 0 よりも微妙に大きい double型であったため、意図した処理ではなくなったように思える。
modf()の仕様的に考えて、よっぽど腐ったライブラリ実装でない限
り、intpartが0より大きく1より小さい値になることはありえないと
考えられます。
実際の問題は、その次の行で不用意にintpartをintにキャストして
いることにあります。
なので、以下のパッチが正しいでしょう。
Index: math.c
--- math.c (revision 25830)
+++ math.c (working copy)
@@ -672,6 +672,7 @@ math_gamma(VALUE obj, VALUE x)
fracpart = modf(d0, &intpart);
if (fracpart == 0.0 &&
0 < intpart &&
- intpart <= INT_MAX &&
(n = (int)intpart - 1) < numberof(fact_table)) {
return DBL2NUM(fact_table[n]);
}
それでは。
--
U.Nakamura usa@garbagecollect.jp
=end
Updated by takano32 (Mitsuhiro TAKANO) over 14 years ago
- Status changed from Assigned to Closed
- % Done changed from 0 to 100
=begin
This issue was solved with changeset r25836.
Mitsuhiro, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.
=end
Updated by takano32 (Mitsuhiro TAKANO) over 14 years ago
=begin
こんにちは
高野です。
U.Nakamura さんは書きました:
こんにちは、なかむら(う)です。
In message "[ruby-dev:39710] [Bug #2381] Math.gammaの挙動がx86_64とia64で異なる"
on Nov.18,2009 11:30:57, redmine@ruby-lang.org wrote:math.cの671行目付近での 0 < intpart という条件式にて intpart が 0 よりも微妙に大きい double型であったため、意図した処理ではなくなったように思える。
modf()の仕様的に考えて、よっぽど腐ったライブラリ実装でない限
り、intpartが0より大きく1より小さい値になることはありえないと
考えられます。実際の問題は、その次の行で不用意にintpartをintにキャストして
いることにあります。
IRCはいろいろ教えていただきありがとうございます。
結局、int型がでてくるのがおかしい、ということになり、
なかださん提案の以下のパッチを r25836 にてコミットしました。
ありがとうございます。 m(_ _)m
Index: math.c¶
--- math.c (revision 25834)
+++ math.c (working copy)
@@ -666,14 +666,13 @@
};
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 && - (n = (int)intpart - 1) < numberof(fact_table)) {
- return DBL2NUM(fact_table[n]);
- intpart - 1 < (double)numberof(fact_table)) {
- return DBL2NUM(fact_table[(int)intpart - 1]);
}
errno = 0;
d = tgamma(d0);
=end