From: Yusuke ENDOH Date: 2010-08-22T22:05:23+09:00 Subject: [ruby-dev:42097] Re: Math::atan2(0, 0) on ruby 1.9.2 遠藤です。 この挙動変更に至るきっかけを作った者 [ruby-core:28206] です。 2010年8月22日17:59 KUBO Takehiro : > と書かれているので、この記述に従うと例外を上げるのもありかなとは思った > けど、2004年版の Single UNIX Specification version 3 では、 私も最初は「盲目的に SUSv3 を手本にすればいい」と思っていたのですが、 ○ エラーのインターフェイスが真似できない (SUSv3 は C 言語ベースなので、「errno に EDOM を設定しつつ値を返す」 ということができるけれど、Ruby だと「Error::EDOM 例外を投げつつ値を 返す」ということができない) ○ SUSv3 にもバグがあるっぽい (例えば SUSv3 だと lgamma(-inf) が +inf を返すと規定されているが、 これは多分未定義が正解) などの理由で、SUSv3 に準拠すればいいという話ではなくなっています。 > 最近のシステムでは atan2(0, 0) の戻り値が実装依存ではなくなってきてお > り、また、"errno may be set to [EDOM]." という記述も消えているので、 > Math::atan2(0, 0) で引数が両方とも 0 ならば Math::DomainError を上げる > というのは止めたほうが良いと思うのですが、どうでしょうか? というわけで SUSv3 との挙動の違いは根拠にならないのですが、「今の挙動だと 実用上困ることがある」などという話があれば、有力な根拠になると思います。 この挙動変更に気がついた状況を説明して頂けるといいかもしれません。 2010年8月22日21:00 Kenta Murata : > この引用で久保さんが仰っている "最近のシステム" に含まれない環境をどう扱うべきかまで含め、 > 久保さんが適切だと考える patch を御自身で作成し、それを提案して頂けると議論を開始できると思います。 やるとしたら、こんな感じ? diff --git a/math.c b/math.c index 23bca55..b73ae30 100644 --- a/math.c +++ b/math.c @@ -55,7 +55,10 @@ math_atan2(VALUE obj, VALUE y, VALUE x) Need_Float2(y, x); dx = RFLOAT_VALUE(x); dy = RFLOAT_VALUE(y); - if (dx == 0.0 && dy == 0.0) domain_error("atan2"); + if (dx == 0.0 && dy == 0.0) { + if (!signbit(dx)) return DBL2NUM(dy); + return DBL2NUM(atan2(dy, -1.0)); + } if (isinf(dx) && isinf(dy)) domain_error("atan2"); return DBL2NUM(atan2(dy, dx)); } -- Yusuke Endoh