Yokohama.rb Monthly Meetup #40 に初参加してきた #yokohamarb

Yokohama.rb Monthly Meetup #40 に初参加してきました。

Doorkeeper

http://yokohamarb.doorkeeper.jp/events/7112

Togetter

http://togetter.com/li/614976

セッション1 Rubyレシピブック読書会

150 浮動小数点数を比較する

レシピブックには、Float:: EPSILONを用いた比較メソッドの例が記載されている。

class Float
  def near_to(b)
    (self - b).abs / abs <= Float::EPSILON &&
    (b - self).abs / b.abs <= Float::EPSILON
  end
end

i = 0.0; 10.times{i += 0.1}
p 1.0.near_to(i) # => true

ただしこの例だと、0.0同士を比較した際にfalseとなってしまう。

class Float
  def near_to(b)
    (self - b).abs / abs <= Float::EPSILON &&
    (b - self).abs / b.abs <= Float::EPSILON
  end
end

i = 0.0;
p 0.0.near_to(i) # => falseとなってしまう!  

これは、4行目および5行目で0除算が発生しており、NaNと比較してしまっていることによる。

[1] pry(main)> 0.0 / 0.0
=> NaN
[2] pry(main)> 0.0 / 0.0 <= Float::EPSILON
=> false

151 乱数を得る

Ruby擬似乱数メルセンヌ・ツイスタによって生成されているとのこと。

Randomクラス

http://docs.ruby-lang.org/ja/1.9.2/class/Random.html

メルセンヌ・ツイスタ

http://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%AB%E3%82%BB%E3%83%B3%E3%83%8C%E3%83%BB%E3%83%84%E3%82%A4%E3%82%B9%E3%82%BF

Ruby 1.9からは、Randomクラスを使用して乱数が生成できる。 また、Marshal.dump/Marshal.loadを使うことでプロセスをまたがって乱数生成器を継続して利用できる。

r = Random.new(1)

p r.rand
p r.rand
data = Marshal.dump(r)
r2   = Marshal.load(data)
p r.rand
p r2.rand

用途としては、シミュレーションを一時中断/再開するときなどかと。 また、種を公開せず暗号学的に安全に乱数を生成するために、SecureRandomクラスが存在する。

require 'securerandom'

p SecureRandom.random_number(8) # 0以上8未満の整数を生成
p SecureRandom.random_bytes(8) # 8バイトのランダムなバイト列
p SecureRandom.hex(8) # random_bytesで得られたバイト列を16進ダンプ
p SecureRandom.base64(8) # random_bytesで得られたバイト列をBase64形式
p SecureRandom.uuid # UUID生成もできる

Karnel#randでもそうだが、引数に0や-1が渡された場合、0~1間の乱数が生成されている模様。

[14] pry(main)> rand(0)
=> 0.7571828230959673
[15] pry(main)> rand(0)
=> 0.863277271836772
[16] pry(main)> rand(0)
=> 0.24270937335089804
[17] pry(main)> SecureRandom.random_number(0)
=> 0.14910422916942845
[18] pry(main)> SecureRandom.random_number(0)
=> 0.7980975369995849
[19] pry(main)> SecureRandom.random_number(0)
=> 0.9364257613698829
[20] pry(main)> SecureRandom.random_number(-1)
=> 0.03216609564230821
[21] pry(main)> SecureRandom.random_number(-1)
=> 0.7975712943150005
[22] pry(main)> SecureRandom.random_number(-1)

Karnel#randomのriを参照してみると、以下の一文が確認できる。

Negative or floating point values for max are allowed, but may give surprising results.

surprising results...

セッション2 @Nabetaniさんからの問題

@miyohideさんが当日のソースを公開してくださっています。 https://github.com/yokohamarb/CoSVON

自分はコーディングには参加せずペアプロを傍から眺めていた身だったが、Gemの作り方、ペアプロ・TDDの回し方など一連の開発過程を見ることができたため、とても貴重な体験となった。

さいごに

Yokohama.rbの皆様ありがとうございました。とても内容の濃い、充実した時間が過ごせたかと思います。

Rubyレシピブック 第3版 303の技

Rubyレシピブック 第3版 303の技