Numeric クラスについて
Upcoming SlideShare
Loading in...5
×
 

Numeric クラスについて

on

  • 657 views

 

Statistics

Views

Total Views
657
Views on SlideShare
657
Embed Views
0

Actions

Likes
0
Downloads
1
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Numeric クラスについて Numeric クラスについて Presentation Transcript

  • Numeric クラスについて 2012/7/21
  • 自己紹介 1 Ruby 暦は かれこれもう10年くらい 近況 docomo の Smartphone を中古で買いました。 mini HDMI 端子がすごい。便利♪ 家のテレビにつながる ケーブルが細いから取り回しがラク Aeon SIM と組合せて、安価に常時接続できてしあわせ 後の勉強会予定 8月4日(土) Making Software 読書会 最終回 今回と同じ会場です 2週間後! みんな来てください。Ruby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Numeric クラスとは 2 Numeric クラスは「数」を抽象化したクラス クラス階層 Numeric (親クラス) Integer (整数を表す) Fixnum (多くの環境で 31bit で表現できる値) Bignum (Fixnum で表現できない整数) Float (浮動小数点数) Rational (有理数) Ruby 1.9 以上で組み込みライブラリに Complex (複素数) Ruby 1.9 以上で組み込みライブラリに 今回説明する範囲 Integer(Fixnum と Bignum)と Float ※ Rational とか Complex は基本的に対象外Ruby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • 今日の進め方について 3 体系的に説明することが難しかったので、 クイズ形式にしました。 1トピック、1問で。 簡単なものもあれば、難しいのもあるかも。 ある程度、みなさんで考えてみてください。Ruby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Rubyクイズ 問題(1)! 4 下記のコードの結果は? p (1/2) 選択肢 A: 0 (Fixnum 型) B: 1 (Fixnum 型) C: (1/2) (Rational 型) D: 0.5 (Float 型)Ruby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Rubyクイズ 解答、解説(1)! 5 答え 0 (Fixnum 型) 解説 Integer# / メソッドは、整数の除算の商を返します。 下記のコードと同じ効果があります。 (1.div 2) #=> 0 0.5 や 有理数の 1/2 を得たい場合は下記のコードを実行します 。 (1.fdiv 2) #=> 0.5 (1.0 / 2) #=> 0.5 (1 / 2.0 ) #=> 0.5 Rational(1) / 2 #=> (1/2)Ruby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Rubyクイズ (2)! 6 【問題】 下記の記述は、正しいか誤っているか? Fixnum や Bignum では新たなメソッドを定義できないRuby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Rubyクイズ 解答、解説(2)! 7 答え Fixnum、Bignum にも新しいメソッド を定義できます。 解説 たとえば、下記のように 1000 という数字を “1,000円” という文字列 に変換するメソッドを Integer クラスに定義できます。 class Integer def tsuuka_hyouji @re ||= /(¥d)(?=(¥d{3})+(?!¥d))/ self.to_s.gsub(@re, ‘¥1,’) + “円” end end num = 10 ** 20 p num.tsuuka_hyoujiRuby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Rubyクイズ (3)! 8 【問題】 下記の記述は、正しいか誤っているか?Fixnum も Bignum も同じ値(num1 == num2)であれば、同じオブジェクト( num1.__id__ == num2.__id__ )である。 Ruby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Rubyクイズ 解答、解説(3)! 9 解説 Fixnum は同じ値であれば同じオブジェクトIDとなりますが、 Bignum はたとえ同じ値でも同じオブジェクトID( num1.__id__ == num2.__id__ ) であるとは限りません。 10.object_id == 10.object_id #=> true (10**10).object_id == (10**10).object_id #=> false Fixnum は値そのものの情報が直接格納されており、メモリの他の場所を参照し たりはしていません。 しかし、Bignum を含む多くの Ruby のオブジェクトは実際の情報はメモリの他 の場所にあります。Bignum の場合、内部的には計算するたびに新たなオブジェ クトが生成されるため、このような挙動になります。 なお、現在の実装では Fixnum のオブジェクトIDは、下記の値になります。 オブジェクトID = ((その Fixnum の値) << 1) | 1 (理由) 内部的にオブジェクトID はポインターであり、ポインターの値は (32bit 処理系では) 必ず 4 の倍数で、奇数にはなりません。Ruby では整数値をコンパクトに表現するため、 ポインターとして使われない奇数を使ったこのような内部表現としています。Ruby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Rubyクイズ (4)! 10 【問題】 下記の記述は、正しいか誤っているか? 下記の ① の計算結果は false だが、 ② の計算結果は true となる。 ① 10**200 == 10**200 + 1 ② 10**200 == 10**200 + 1.0Ruby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Rubyクイズ 解答、解説(4)! 11 答え 正しい記述です。 解説 下記の ① の計算結果は false だが、 ② の計算結果は true となる。 10**200 == 10**200 + 1 10**200 == 10**200 + 1.0 前提知識を整理します。 • Bignum は任意の整数を正確に扱うが、Float は近似値である。 • Bignum + Fixnum は Bignum であり、Bignum + Float は Float となる • Bignum と Float を == で比較するときは Bignum を Float に変換したと きに同じ値になるかで評価される。 • 浮動小数点の10進数での精度は、Float::DIG 桁(15桁) これらの前提をもとに考えると、 この場合、10**200 に1だけ異なるような場合は、 Float クラスでは同一の値として内部的に表現されます。Ruby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Rubyクイズ (5)! 12 【問題】 下記の記述は、正しいか誤っているか? 下記の ① は 3 になるが、 ② は “12” になる。 ①: 1 + “2” ②: “1” + 2Ruby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Rubyクイズ 解答、解説(5)! 13 答え 誤っています。 解説 下記の ① は 3 になるが、 ② は “12” になる。 ①: 1 + “2” ②: “1” + 2この選択肢の ① と ② の両方とも実際にはエラーとなります。 > 1+”2” TypeError: String cant be coerced into Fixnum > “1”+2 TypeError: cant convert Fixnum into StringRuby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Rubyクイズ 解答、解説(5)! 14 解説 String#coerce を定義すると、 1 + “2” を 3 にすることができます。 class String def coerce(other) coerced= case other when Integer self.to_i when self.to_f end return coerced, other end end p(1 + “2”) #=> 3Ruby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Rubyクイズ 解答、解説(5)! 15 解説 Integer#to_str を定義すると、 “1” + 2 を “12” にすることができます。 class Integer def to_str to_s end end p(“1” + 2) #=> “12”Ruby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Rubyクイズ (6)! 16 【問題】 下記の記述は、正しいか誤っているか? 下記の ① は エラーになるが、 ② はエラーにならない。 ①: 1/0 ②: 1.0/0Ruby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Rubyクイズ 解答、解説(6)! 17 解説 下記の ① は エラーになるが、 ② はエラーにならない。 ①: 1/0 ②: 1.0/0 これは正しい記述となっています。 ① の場合は ZeroDivisionError となります。 ② の場合は+Infinity という浮動小数点数(Float型の値)となります。 irb> 1/0 ZeroDivisionError: divided by 0 from (irb):1:in `/ from (irb):1 irb> 1.0 /0 => Infinity irb> (1.0/0).class => FloatRuby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Rubyクイズ 解答、解説(6)! 18 補足 +Infinity は実はいろいろと便利です。特に無限リストと @yhara さん作の Enumerable#lazy と組合せると面白いことができます。 > gem install enumerable-lazy # ruby 2.0 では標準添付 > irb irb> require enumerable/lazy => true irb> infinity = 1/0.0 => Infinity irb> (1..infinity).lazy.map{|i| i*i}.take(5).to_a => [1, 4, 9, 16, 25] (1..infinity) は 初期値(1) から Object#succ を繰り返し実行し、infinity を超えない オブジェクトを順に生成します。つまり無限に整数を生成します。 このような操作には従来であれば無限長の配列が必要ですが、 Enumerable#lazy によって map などのメソッドを使っているにも関わらず必要な 分しか生成しないことにより、有限なメモリ空間で実行可能になります。Ruby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Rubyクイズ (7)! 19 【問題】 正しい選択肢を選べ quo, mod = (-2.0).divmod -3 を実行すると、 A: quo は 1、 mod は 1 となる B: quo は 1、 mod は 1.0 となる C: quo は 0、 mod は -2 となる D: quo は 0、 mod は -2.0 となるRuby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • Rubyクイズ 解答、解説(7)! 20 答え B quo, mod = (-2.0).divmod -3 の quo は -1, mod は 1.0 解説 Numeric#divmod は、除算の商と剰余を配列で返します。 たとえば、下記のような演算になります。 7.divmod(2) #=> [3, 1] このとき、商と剰余は下記のようになります。 ・ 商(この場合の 3)は必ず整数 ・ 被除数(この場合は 7) も除数(この場合は2)も整数(Integer)であれば、 剰余(この場合の1)も整数(Integer) ・ 被除数か除数のどちらかが Float であれば 剰余も Float ・ 剰余は必ず 正かゼロの値(Numeric) quo, mod = (-2.0).divmod -3 の場合は quo は 1、 mod は -1.0 となります。Ruby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • まとめ 21 小ネタ的な Numeric クラスにまつわるクイズ集でした 楽しんでもらえたら、うれしいです。Ruby/Rails勉強会@関西 第55回 「Numeric クラスについて」
  • 22ご清聴ありがとう ございました