Bug #2381

Math.gammaの挙動がx86_64とia64で異なる

Added by takano32 (Mitsuhiro TAKANO) over 2 years ago. Updated about 1 year ago.

[ruby-dev:39709]
Status:Closed Start date:11/18/2009
Priority:Low Due date:
Assignee:takano32 (Mitsuhiro TAKANO) % Done:

100%

Category:core
Target version:-
ruby -v:ruby 1.9.2dev (2009-11-17 trunk 25805)

Description

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" を返却している。

math.c.diff - math_gamma の修正 (425 Bytes) takano32 (Mitsuhiro TAKANO), 11/18/2009 11:29 am

math.c.diff (644 Bytes) takano32 (Mitsuhiro TAKANO), 11/18/2009 11:50 am

math.c.diff (644 Bytes) takano32 (Mitsuhiro TAKANO), 11/18/2009 11:58 am

Associated revisions

Revision 25836
Added by takano32 (Mitsuhiro TAKANO) over 2 years ago

* math.c (math_gamma): fix incorrect comparison expression. see also [ruby-dev:39709] [Bug #2381]

Revision 25836
Added by takano32 (Mitsuhiro TAKANO) over 2 years ago

* math.c (math_gamma): fix incorrect comparison expression. see also [ruby-dev:39709] [Bug #2381]

History

Updated by takano32 (Mitsuhiro TAKANO) over 2 years ago

math.cの671行目付近での 0 < intpart という条件式にて intpart が 0 よりも微妙に大きい double型であったため、意図した処理ではなくなったように思える。

該当部分のパッチを添付する。

Updated by usa (Usaku NAKAMURA) over 2 years ago

こんにちは、なかむら(う)です。

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>

Updated by takano32 (Mitsuhiro TAKANO) over 2 years ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100
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.

Updated by takano32 (Mitsuhiro TAKANO) over 2 years ago

こんにちは
高野です。

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);

Also available in: Atom PDF