From: KUBO Takehiro Date: 2010-08-22T22:58:05+09:00 Subject: [ruby-dev:42101] Re: Math::atan2(0, 0) on ruby 1.9.2 久保です。 2010/8/22 Yusuke ENDOH : > 私も最初は「盲目的に 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 との挙動の違いは根拠にならないのですが、「今の挙動だと > 実用上困ることがある」などという話があれば、有力な根拠になると思います。 > この挙動変更に気がついた状況を説明して頂けるといいかもしれません。 えーと、「実用上困ること」という話はありません。もともと atan2() を実 アプリで使ったことは一度もないし....。 気付いた背景を説明すると、私の作っている ruby-oci8 という Oracle ライ ブラリのテストケースの失敗が発端でした。Oracle のクライアントライブラ リには10進数38桁の精度をもつ NUMBER 型(内部的には100進数19桁)に対する 数値関数が定義されていて、OCI関数 OCINumberArcTan2() に対応する ruby側 の関数としてOCI8::Math::atan2() が定義されています。この関数の動作テス トとして演算結果の比較のために Math::atan2() を使用していたわけです。 で、Math::atan2(0, 0) が例外を上げるようになった結果、テストケースに失 敗するようになったと。 むしろ、例外が上がるようになって ruby-oci8 的には好都合なこともありま す。元々、OCINumberArcTan2() は二番目の数値が 0 のときはエラーになる仕 様でして、Math::atan2() の動作に合わせるための特別処理を入れてたのです が、Oracle の NUMBER 型には +0/-0 の区別がないので、100%合わせることは 不可能でした。しかし、ruby の Math::atan2(0, 0) が例外を上げるようになっ たので、同じ動作をさせることが可能となった。こういう点から見ると逆に好 都合なわけです。 前のメールで > 了解です。手元の案件が終わったら、やってみます。 と書いたけど、「SUSv3 との挙動の違いは根拠にならない」という話を含めて もう少し考えてからにします。(結局やらないという結論になるかも)