Feature #2968
数値の正負を返すメソッド
| Status: | Assigned | Start date: | 03/16/2010 | |
|---|---|---|---|---|
| Priority: | Normal | Due date: | ||
| Assignee: | % Done: | 0% |
||
| Category: | core | |||
| Target version: | - |
Description
数値の正負を返すメソッドが欲しいです。 主たる想定用途は 0.0 と -0.0 を区別したいときです。 これは、0.0 > -0.0 や 0.0 == -0.0 では知ることができません。 とりあえず flo.to_s[0] == ?- で知ることができますが、これではあんまりです。 悩みどころはいつもの通りメソッド名ですが、 * Numeric#positive? と Numeric#negative? * Numeric#sign -> 負で -1、正で 1 * Numeric#sign? -> 負で true, 正で false (signbit(3) に習う) あたりでしょうか。 いかがでしょう。
Related issues
History
Updated by mrkn (Kenta Murata) about 2 years ago
村田です。 On 2010/03/16, at 3:38, Yui NARUSE wrote: > 数値の正負を返すメソッドが欲しいです。 > 主たる想定用途は 0.0 と -0.0 を区別したいときです。 > これは、0.0 > -0.0 や 0.0 == -0.0 では知ることができません。 > とりあえず flo.to_s[0] == ?- で知ることができますが、これではあんまりです。 > > 悩みどころはいつもの通りメソッド名ですが、 > * Numeric#positive? と Numeric#negative? > * Numeric#sign -> 負で -1、正で 1 > * Numeric#sign? -> 負で true, 正で false (signbit(3) に習う) > あたりでしょうか。 Numeric#sign? よりは、Numeric#positive? と Numeric#negative? を提供する 方が私は好きです。 Numeric#sign も同時に提供されていて良いと思います。 ところで、これらのメソッドは Complex ではどのように振舞うんでしょう? * Numeric で提供するメソッドは実部についての符号を扱い、 虚部については Complex で同類のメソッドを提供する。 * Numeric で提供するメソッドを Complex からは undef する。 実部や虚部の符号が知りたい場合は Complex#real.positive? のようにする。 この2パターンが思いつきました。 -- Kenta Murata OpenPGP FP = FA26 35D7 4F98 3498 0810 E0D5 F213 966F E9EB 0BCC 本を書きました!! 『Ruby 逆引きレシピ』 http://www.amazon.co.jp/dp/4798119881/mrkn-22 E-mail: mrkn@mrkn.jp twitter: http://twitter.com/mrkn/ blog: http://d.hatena.ne.jp/mrkn/
Updated by shyouhei (Shyouhei Urabe) about 2 years ago
- Status changed from Open to Rejected
f > 0 or 1.0 / f > 0 ではなんでだめなんですか?
Updated by naruse (Yui NARUSE) about 2 years ago
実数のみの想定でしたので、Numericではなく、Integer, Float, Rational 個別に定義した方が良かったかもしれません。 > f > 0 or 1.0 / f > 0 ではなんでだめなんですか? workaround としてはそちらの方がよいですね、ありがとうございます。 しかし、この方法でもまだ、1ビット読めばいいものを無駄に複雑にやっていませんか。
Updated by mrkn (Kenta Murata) about 2 years ago
むらたです。 On 2010/03/16, at 8:04, Shyouhei Urabe wrote: > f > 0 or 1.0 / f > 0 > > ではなんでだめなんですか? 前者では -0.0 の符号を調べられません。 かといって後者よりは negative? と書かれている方が 分かりやすい気がします。 もう一点気になることは、1.0 / -0.0 で -Infinity が得られる事が アーキテクチャに依存せず決まっているのかどうかです。 -- Kenta Murata OpenPGP FP = FA26 35D7 4F98 3498 0810 E0D5 F213 966F E9EB 0BCC 本を書きました!! 『Ruby 逆引きレシピ』 http://www.amazon.co.jp/dp/4798119881/mrkn-22 E-mail: mrkn@mrkn.jp twitter: http://twitter.com/mrkn/ blog: http://d.hatena.ne.jp/mrkn/
Updated by naruse (Yui NARUSE) about 2 years ago
(f > 0 or 1.0 / f > 0) という趣旨かと思います。 で、そもそもの動機は doubleを生成するメソッドのテストをする際に、 d = -0.0 assert_equal(0, d) assert_equal(-INFINITY, 1.0/d) などと書くのは冗長というのがありました。 1.0/-0.0 は VAX だとどうなんでしょうね。
Updated by shyouhei (Shyouhei Urabe) about 2 years ago
Yui NARUSE さんは書きました: > (f > 0 or 1.0 / f > 0) という趣旨かと思います。 そうです。 > で、そもそもの動機は doubleを生成するメソッドのテストをする際に、 > d = -0.0 > assert_equal(0, d) > assert_equal(-INFINITY, 1.0/d) > などと書くのは冗長というのがありました。 それはsignが欲しいんじゃなくて==よりもstrictな等値判定が欲しいという話では > 1.0/-0.0 は VAX だとどうなんでしょうね。 持ってないので存じ上げませんがべつに1.0/-0.0が-Infを生成する必要はなくて、-0.0 より小さい何かを生成すればよいので。 Attachment: signature.asc
Updated by naruse (Yui NARUSE) about 2 years ago
> > で、そもそもの動機は doubleを生成するメソッドのテストをする際に、 > > d = -0.0 > > assert_equal(0, d) > > assert_equal(-INFINITY, 1.0/d) > > などと書くのは冗長というのがありました。 > > それはsignが欲しいんじゃなくて==よりもstrictな等値判定が欲しいという話では この例に関してはそうですね。 Float#eql? は 0.0 と -0.0 を区別する、とかでも。 別に正負判定は欲しくなることがたまにあるのですが、たいていは n >= 0 でよいので主張として弱くはなります。 NaN の符号もバイナリを見ないと判定できないけど、使わないしなぁ
Updated by naruse (Yui NARUSE) about 2 years ago
成瀬です。 2010年3月16日11:37 KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>: >> チケット #2968 が更新されました。 (by Yui NARUSE) >> >> >> 実数のみの想定でしたので、Numericではなく、Integer, Float, Rational 個別に定義した方が良かったかもしれません。 >> >> > f > 0 or 1.0 / f > 0 ではなんでだめなんですか? >> workaround としてはそちらの方がよいですね、ありがとうございます。 >> しかし、この方法でもまだ、1ビット読めばいいものを無駄に複雑にやっていませんか。 > > 想定用途が組込みクラスのテストケースだとすると、うれしい人はとても > 少なそうです。 > 多少冗長な書き方になっていてもかまわないのでは? 用途としてはとりあえずテストケースなのですが、背景としては Float の浮動小数点数としての 内部構造が隠蔽されすぎているという点を問題視しています。 符号だけでなく、Floatの仮数部や指数部もとれないとか。 -- NARUSE, Yui naruse@airemix.jp
Updated by naruse (Yui NARUSE) about 2 years ago
2010年3月16日13:27 KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>: >> 成瀬です。 >> >> 2010年3月16日11:37 KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>: >> >> チケット #2968 が更新されました。 (by Yui NARUSE) >> >> >> >> >> >> 実数のみの想定でしたので、Numericではなく、Integer, Float, Rational 個別に定義した方が良かったかもしれません。 >> >> >> >> > f > 0 or 1.0 / f > 0 ではなんでだめなんですか? >> >> workaround としてはそちらの方がよいですね、ありがとうございます。 >> >> しかし、この方法でもまだ、1ビット読めばいいものを無駄に複雑にやっていませんか。 >> > >> > 想定用途が組込みクラスのテストケースだとすると、うれしい人はとても >> > 少なそうです。 >> > 多少冗長な書き方になっていてもかまわないのでは? >> >> 用途としてはとりあえずテストケースなのですが、背景としては Float の浮動小数点数としての >> 内部構造が隠蔽されすぎているという点を問題視しています。 >> 符号だけでなく、Floatの仮数部や指数部もとれないとか。 > > Cでもとれないですよね > 仮数部、指数部 > で、それで困るという話もあまり聞きません。 frexp(3) でとれますね。 > FortranやCで数値計算するときも、if (val < 目標精度) みたいな書き方で > なんとかなっているという認識。 > > なので、その背景のさらにバックグラウンドがあると思うのですが、 > ちょっと思い浮かびませんでした。 %a 絡みの処理を書いていて、バイナリとしてはすぐそこにあるはずのものが、 Ruby レイヤだとかなり手間をかけないと取れない理不尽さ、かな。 わたしが知らないだけなのかもしれませんが、現状指数部・仮数部を取るのって、 結構大変ですよね。 -- NARUSE, Yui naruse@airemix.jp
Updated by naruse (Yui NARUSE) about 2 years ago
2010年3月16日15:16 KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>: >> > > FortranやCで数値計算するときも、if (val < 目標精度) みたいな書き方で >> > > なんとかなっているという認識。 >> > > >> > > なので、その背景のさらにバックグラウンドがあると思うのですが、 >> > > ちょっと思い浮かびませんでした。 >> > >> > %a 絡みの処理を書いていて、バイナリとしてはすぐそこにあるはずのものが、 >> > Ruby レイヤだとかなり手間をかけないと取れない理不尽さ、かな。 >> > わたしが知らないだけなのかもしれませんが、現状指数部・仮数部を取るのって、 >> > 結構大変ですよね。 >> >> いや、大変なのは確かだと思います。 >> なので、ユースケースさえあればまったく反対しません >> >> IEEE754前提の定義・実装でも誰も困らないと思うので、あまり揉めないと思うし > > さらに後から気がつきましたが、Rubyにも Math.frexp() がすでにありますよね。 > これで不足な理由はなんでしたっけ? おおう、それに気づきませんでした。 それでよいと思います。 それじゃ Math.signbit() があればいいな -- NARUSE, Yui naruse@airemix.jp
Updated by knu (Akinori MUSHA) over 1 year ago
- Status changed from Rejected to Assigned
- Assignee set to mrkn (Kenta Murata)
フィードバックがあるのにRejectedのままなので再開します。 ・positive? は >0 でも良いので不要 ・Math.signbit?(num) だと新しい数クラスに対応できない というところから、 Numeric#negative? を導入するのはでどうでしょうか。 (Numericでの定義はnilで、符号が定義される各派生クラスでオーバーライドしてtrue/falseを返す) Numeric#sign も、あれば同符号判定が楽になるかもしれません。