[ruby-list:47276] Re: case when 整数と実数の比較 (ruby 1.9)

From: 小田 利通 <oda@...>
Date: 2010-07-31 00:58:58 UTC
List: ruby-list #47276
  小田利通です。るびきちさん、ささださん、ありがとうございます。

From: SASADA Koichi <ko1@atdot.net>
Subject: Re: [ruby-list:47272] case when 整数と実数の比較 (ruby 1.9)
Date: Fri, 30 Jul 2010 22:23:35 +0900

》(コンパイル時に when が簡単なリテラルだけなら hash をひくように効率化し
》ているんですが、
》 p({1 => true}[1.0]) #=> nil

  ハッシュは eql? ですし、 case は === なので、むずかしいように思います。

  その上、どちらも再定義可能な演算子ですから、実行時にどうなるんでしょうね。

  この「効率化」は when がたくさん並んだときでなく、
when の後ろに , で区切ってたくさん並んだときに効率良く処理するものですよね。

  case var
  when 1,2,3,4,8,10,11,13;

  こういうときに(eql? を使っても良くて)効率良く処理したければ、自分で
あらかじめハッシュを用意して置くべきかもしれません。


  time ruby -e 'var=13; 200000.times {case var; when 1,2,3,4,7,11,13; true;end}'
   # ruby 1.8 では遅いけど、現在の ruby 1.9.1 では早い

  time ruby -e 'var=13; hsh={1=>true,2=>true,3=>true,4=>true,7=>true,11=>true,13=>true};200000.times {case;when hsh[var];true ;end}'
   # これも同程度に早い

  time ruby -e 'var=13; ary=[1,2,3,4,7,11,13]; 200000.times {case;when ary.index(var);true;end}'
   # 配列は遅い  比較は == を使用

 ary のように、キーが重要で、値はそれほど重要でないハッシュが、
もっとの簡単に書けると良いのですけどね。



From: rubikitch@ruby-lang.org
Subject: [ruby-list:47273] Re: case when 整数と実数の比較 (ruby 1.9)
Date: Fri, 30 Jul 2010 18:25:01 +0900

》ですが、そもそも浮動小数点数で直接比較するものではありません。
》丸め誤差の関係で思わぬ落とし穴にはまります。

  そうですね。実際に私が書いているコードは

  case var
  when 1; 

というのだったんですが、var は実質整数である、Float のオブジェクトと
分かっているので、

  case var.to_i   ## or var.round
  when 1; 

とするのが良いのですね。
  ありがとうございます。

T.Oda

In This Thread

Prev Next