Project

General

Profile

Actions

Bug #2381

closed

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

Added by takano32 (Mitsuhiro TAKANO) over 14 years ago. Updated almost 13 years ago.

Status:
Closed
Target version:
-
ruby -v:
ruby 1.9.2dev (2009-11-17 trunk 25805)
Backport:
[ruby-dev:39709]

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

math.c.diff (425 Bytes) math.c.diff math_gamma の修正 takano32 (Mitsuhiro TAKANO), 11/18/2009 11:29 AM
math.c.diff (644 Bytes) math.c.diff takano32 (Mitsuhiro TAKANO), 11/18/2009 11:50 AM
math.c.diff (644 Bytes) math.c.diff takano32 (Mitsuhiro TAKANO), 11/18/2009 11:58 AM
Actions #1

Updated by takano32 (Mitsuhiro TAKANO) over 14 years ago

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

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

Actions #2

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, 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

=end

Actions #3

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

Actions #4

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, 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

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0