たのしいRuby 第10章 Numericクラス

ここからまたirb作業に入る。

2のn乗

サンプルでは、2の1000乗まで計算していた。

p 2**1000
107150860718626732094842504906000181056140481170553360744375038837035105
112493612249319837881569585812759467291755314682518714528569231404359845
775746985748039345677748242309854210746050623711418779541821530464749835
819412673987675591655439460770629145711964776865421676604298316526243868
37205668069376

凄いね。何処までいけるのか・・・。

p 2**262144
...(略
4326499137387203650107299993809500432559730753862605349934298300416

ここまでできた。バイナリサーチ法で地道にやってしまった。実は・・・

p 2**0x40000
...(略
4326499137387203650107299993809500432559730753862605349934298300416

16進数でやれば一発で出た。では、何桁になるのか・・・

p (2**0x40000).to_s.size
78914

7万8千桁。ありえん。

ドットがパイプに見えてきた。

0演算を捉えろ

irb(main):067:0> begin
irb(main):068:1*  1 / 0
irb(main):069:1> rescue => ex
irb(main):070:1>  p ex
irb(main):071:1>  puts ex.message
irb(main):072:1> end
#<ZeroDivisionError: divided by 0>
divided by 0
=> nil

エラー処理も段々慣れてきた。irbだとrescue ZeroDivisionErrorで補足出来ない。かなりハマった。

ハマったついでに良リンク発見

Ruby - あさあさの公開メモ
ZaurusRuby、そこから巡って・・・
逆引きRuby/Qt
Qt出来ちゃうなんて・・・。
逆引き Ruby - Google Search
googleで逆引きを調べたら大量に出てきた。"逆引き"キーワード。イケル!!

数値型の変換

irb(main):128:0> "ほげ 45".to_i
=> 0
irb(main):129:0> "123 45".to_i
=> 123
irb(main):131:0> "123_45".to_i
=> 12345
irb(main):134:0> "0x12345".to_i
=> 0
irb(main):135:0> "012345".to_i
=> 12345
  • 文字なら0を返す
  • 途中で空白が入ったりしてると、解析出来るところまで。
  • "123_45"は変換可能だが、
  • "0x12345"は変換出来ない。
  • "012345"は8進数ではなく、整数。

むむ・・・。

roundの挙動について

本書とは関係ないけど、何処かでハマった気がする。銀行丸め。偶数丸め・・・

ややこしいんだこれが・・・。0.1で丸めたとき、

  • 12.5の時は12に丸める
  • 13.5の時は14に丸める

処理系によってはこちらを採用しているケースがある。Rubyのroundは四捨五入。

必ず確認した方がいい。ハマる。

ビット演算

マイナスのビット演算も罠がいっぱいだ。

irb(main):156:0> 256 >> 4
=> 16
irb(main):157:0> 256 >> 6
=> 4
irb(main):158:0> 256 >> 8
=> 1
irb(main):159:0> 256 >> 10
=> 0

結果はゼロになる。問題はマイナスのビットシフト。

irb(main):160:0> -256 >> 4
=> -16
irb(main):161:0> -256 >> 6
=> -4
irb(main):162:0> -256 >> 8
=> -1
irb(main):163:0> -256 >> 10
=> -1

結果は-1。ゼロでは無い。

高速除算の代わりに使うと罠にハマる。←ハマったひと。

&

&はよく使うので覚えておくと便利かも。(使わないって

ビットの5桁目が0か1かを判断する。

irb(main):219:0> ((0xff & 0x10) >> 4)
=> 1
irb(main):220:0> ((0xef & 0x10) >> 4)
=> 0

マスクしてビットシフト。OS自作er必修技。便利!!

って、Rubyでは絶対使わないな・・・バイナリアンtanaka暴走気味・・・。

数え上げ

id:samurai20000さんにツッコミを頂いたので、修正を加える。

irb(main):004:0> 10.times do |i|
irb(main):005:1*  print "#{i} "
irb(main):006:1> end
0 1 2 3 4 5 6 7 8 9 => 10

#{}は便利っすねぇ。

bashの${}もメチャメチャ便利。使いこなしてないけどね・・・

また不思議なやつ

irb(main):001:0> array = []
=> []
irb(main):002:0> 2.upto(10) do |i|
irb(main):003:1*  array << i
irb(main):004:1> end
=> 2
irb(main):005:0> p array
[2, 3, 4, 5, 6, 7, 8, 9, 10]
=> nil

<<演算子は便利っすね。C++のストリームみたいな感じ。

irb(main):013:0> array >> i
NoMethodError: undefined method `>>' for [2, 3, 4, 5, 6, 7, 8, 9, 10]:Array
        from (irb):13
        from :0

逆で取り出せるかなぁと思ったけど、無かった・・・。残念。

downto,stepも便利。for文はいらないっすねぇ・・・

練習問題

  • 1,2,3は回答の方がセクシーに解いてた。
  • 4の素数はわからなかったので、回答をみた。なるほど・・・。return false if num < 2がrubyっぽい。優先順位が不明になってきた。アルゴリズムも見直さないとなぁ・・・。

凹みながら10章終了〜。