Project

General

Profile

Actions

Feature #2968

closed

数値の正負を返すメソッド

Added by naruse (Yui NARUSE) over 14 years ago. Updated about 7 years ago.

Status:
Rejected
Target version:
[ruby-dev:40649]

Description

=begin
数値の正負を返すメソッドが欲しいです。
主たる想定用途は 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) に習う)
    あたりでしょうか。

いかがでしょう。
=end


Related issues 1 (0 open1 closed)

Has duplicate Ruby master - Feature #5523: Numeric#sign の追加Closed10/31/2011Actions
Actions #1

Updated by mrkn (Kenta Murata) over 14 years ago

=begin
村田です。

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:
twitter: http://twitter.com/mrkn/
blog: http://d.hatena.ne.jp/mrkn/

=end

Actions #2

Updated by shyouhei (Shyouhei Urabe) over 14 years ago

  • Status changed from Open to Rejected

=begin
f > 0 or 1.0 / f > 0

ではなんでだめなんですか?
=end

Actions #3

Updated by naruse (Yui NARUSE) over 14 years ago

=begin
実数のみの想定でしたので、Numericではなく、Integer, Float, Rational 個別に定義した方が良かったかもしれません。

f > 0 or 1.0 / f > 0 ではなんでだめなんですか?
workaround としてはそちらの方がよいですね、ありがとうございます。
しかし、この方法でもまだ、1ビット読めばいいものを無駄に複雑にやっていませんか。
=end

Actions #4

Updated by mrkn (Kenta Murata) over 14 years ago

=begin
むらたです。

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:
twitter: http://twitter.com/mrkn/
blog: http://d.hatena.ne.jp/mrkn/

=end

Actions #5

Updated by naruse (Yui NARUSE) over 14 years ago

=begin
(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 だとどうなんでしょうね。
=end

Actions #6

Updated by shyouhei (Shyouhei Urabe) over 14 years ago

=begin
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
=end

Actions #7

Updated by naruse (Yui NARUSE) over 14 years ago

=begin

で、そもそもの動機は 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 の符号もバイナリを見ないと判定できないけど、使わないしなぁ
=end

Actions #8

Updated by naruse (Yui NARUSE) over 14 years ago

=begin
成瀬です。

2010年3月16日11:37 KOSAKI Motohiro :

チケット #2968 が更新されました。 (by Yui NARUSE)

実数のみの想定でしたので、Numericではなく、Integer, Float, Rational 個別に定義した方が良かったかもしれません。

f > 0 or 1.0 / f > 0 ではなんでだめなんですか?
workaround としてはそちらの方がよいですね、ありがとうございます。
しかし、この方法でもまだ、1ビット読めばいいものを無駄に複雑にやっていませんか。

想定用途が組込みクラスのテストケースだとすると、うれしい人はとても
少なそうです。
多少冗長な書き方になっていてもかまわないのでは?

用途としてはとりあえずテストケースなのですが、背景としては Float の浮動小数点数としての
内部構造が隠蔽されすぎているという点を問題視しています。
符号だけでなく、Floatの仮数部や指数部もとれないとか。

--
NARUSE, Yui

=end

Actions #9

Updated by naruse (Yui NARUSE) over 14 years ago

=begin
2010年3月16日13:27 KOSAKI Motohiro :

成瀬です。

2010年3月16日11:37 KOSAKI Motohiro :

チケット #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

=end

Actions #10

Updated by naruse (Yui NARUSE) over 14 years ago

=begin
2010年3月16日15:16 KOSAKI Motohiro :

FortranやCで数値計算するときも、if (val < 目標精度) みたいな書き方で
なんとかなっているという認識。

なので、その背景のさらにバックグラウンドがあると思うのですが、
ちょっと思い浮かびませんでした。

%a 絡みの処理を書いていて、バイナリとしてはすぐそこにあるはずのものが、
Ruby レイヤだとかなり手間をかけないと取れない理不尽さ、かな。
わたしが知らないだけなのかもしれませんが、現状指数部・仮数部を取るのって、
結構大変ですよね。

いや、大変なのは確かだと思います。
なので、ユースケースさえあればまったく反対しません

IEEE754前提の定義・実装でも誰も困らないと思うので、あまり揉めないと思うし

さらに後から気がつきましたが、Rubyにも Math.frexp() がすでにありますよね。
これで不足な理由はなんでしたっけ?

おおう、それに気づきませんでした。
それでよいと思います。

それじゃ Math.signbit() があればいいな

--
NARUSE, Yui

=end

Actions #11

Updated by knu (Akinori MUSHA) over 14 years ago

  • Status changed from Rejected to Assigned
  • Assignee set to mrkn (Kenta Murata)

=begin
フィードバックがあるのにRejectedのままなので再開します。

・positive? は >0 でも良いので不要
・Math.signbit?(num) だと新しい数クラスに対応できない

というところから、 Numeric#negative? を導入するのはでどうでしょうか。
(Numericでの定義はnilで、符号が定義される各派生クラスでオーバーライドしてtrue/falseを返す)

Numeric#sign も、あれば同符号判定が楽になるかもしれません。
=end

Updated by mrkn (Kenta Murata) about 13 years ago

#5523 でも Numeric#sign が提案されてますね。
positive? や negative? は複素数に対応できないという #5513 でのまつもとさんの意見は確かに尤もだと思いました。

分かってないのは Complex#sign の挙動です。どう動けば良いんですかね?

Updated by hasari (Hiro Asari) over 12 years ago

#5523 でも触れましたが Complex#sign は z/|z| を返すのが数学的に一番よろしいかと思います。ふなばさんは #5523 では「複素数はエラーを考えています。」と仰っています。

Updated by yhara (Yutaka HARA) about 12 years ago

  • Target version set to 2.6

Updated by mame (Yusuke Endoh) about 7 years ago

5 年ほど議論が無いので一旦 close します。必要なら、現状を再確認の上、reopen や再提案をするといいと思います。
ちょっと調べたところ、positive? や negative? は #11151 で導入されましたが、(-0.0).negative? は false になるようです。

Actions #16

Updated by mame (Yusuke Endoh) about 7 years ago

  • Status changed from Assigned to Rejected
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0