たのしいRuby(第2版) 「はじめてのRuby」〜数値の表示と計算〜

■これは「たのしいRuby 第2版」を元にしています。
Amazon CAPTCHA

Rubyのプログラムでは、整数や小数(浮動小数点数)を、自然な形で扱うことができます。

数値の表示

Rubyでは文字列は文字列オブジェクトという形になっている」と説明しました。同じように、数値も「数値オブジェクト」として扱われます。

Rubyで整数のデータを表現するのは簡単です。そのまま数字を並べて書けばよいだけです。

1

と書けば「1」の値の整数(Fixnum)オブジェクトになります。また、

100

と書けば、「100」の整数オブジェクトになります。さらに、

3.1415

などと書けば、「3.1415」の値の浮動小数点数(Float)オブジェクトになります。

※「Fixnum」や「Float」というのは、それぞれのオブジェクトが所属する「クラス」の名前です。


数値を表示するには、文字列と同様にprintメソッドやputsメソッドを使います。

ふむふむ。なるほど。やってみましょう。

  • プログラム
puts 1
puts 100
puts 3.1415

puts 1.class
puts 100.class
puts 3.1415.class
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
1
100
3.1415
Fixnum
Fixnum
Float

なるほど、書いてある通りですね。



四則演算

数の計算を行ったり、その結果を表示したりすることもできます。四則演算をやってみましょう。

はーい。

  • プログラム
print "1 + 1 = ", 1 + 1, "\n"
print "2 - 3 = ", 2 - 3, "\n"
print "5 * 10 = ", 5 * 10, "\n"
print "100 / 4 = ", 100 / 4, "\n"
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
1 + 1 = 2
2 - 3 = -1
5 * 10 = 50
100 / 4 = 25

おおお。計算できました。

プログラミングの世界では、掛け算の記号に「*」を、割り算の記号に「/」を使うのが一般的です。Rubyもこの習慣にならっています。


ちょっと意地悪して、2つほど実験してみましょう。

四則演算の実験1

  • プログラム
print "10 / 3 = ", 10 / 3
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
10 / 3 = 3

ちょwwwwwテラうそつきwwwwwww
ゆとり教育の「円周率は3」的な匂いを感じます。


四則演算の実験2

  • プログラム
y = 0
for i in 1..100
y = 0.1+y
end

print y

上記は、0.1 を100回足すというプログラムです。単純に考えると、答えは10ですよね。

  • 実験結果
C:\enjoy_ruby>ruby helloruby.rb
9.99999999999998

ちょwwwwwwテラうそつきwwwwwww
コンピュータが壊れたのでしょうか?



では、謎を解いていきましょう。



四則演算の実験1の謎

10 / 3 = 3
うーん。普通は3.33333333・・・ とかになりますよね。
なぜ 3 なのか。


それは、
整数と浮動小数点数の演算結果 - 数値と四則演算 - Ruby入門
こちらに書いてあります。

演算を行う場合、整数と整数、浮動小数点数浮動小数点数だけではなくに整数と浮動小数点数に対して演算を行うことも可能です。ただし演算の結果得られる数値が整数になるか浮動小数点数になるかは注意が必要です。

左辺 右辺 演算結果
整数 整数 整数
整数 浮動小数点数 浮動小数点数
浮動小数点数 整数 浮動小数点数
浮動小数点数 浮動小数点数 浮動小数点数


つまり、整数と整数の演算だったので、出力も整数になるというものです。


ですので、どちらかを浮動小数点数でかけば、3.33333〜みたいな出力結果になるはずです。やってみましょう。

  • プログラム
print "10.0 / 3 = ", 10.0 / 3
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
10.0 / 3 = 3.33333333333333

ktkr でたー!
しかし、なぜ 3.33333333333333 なのでしょうか。
3.33333333333333... みたいなエンドレスマークがついてもよい気もしますが・・・。


それは、
まつもと直伝 プログラミングのオキテ 第15回 浮動小数点数の謎に満ちた世界(2ページ目) | 日経 xTECH(クロステック)
こちらに書いてあります。

浮動小数点数は有限である
 数学上の数は無限のケタを持つことがありますが,浮動小数点数は有限の情報しか持てません。浮動小数点数は単精度(float)で32ビット,倍精度で64ビットしかありません。このビット数で表現できる数には限りがあるのです。


・・・あってるのかな?wwつっこみ歓迎ですwwww


四則演算の実験2の謎

0.1 を100回足すというプログラムです。単純に考えると、答えは10ですよね。
なぜ、Ruby(コンピュータ)は 9.99999999999998 と回答するのでしょうか。


それは、コンピュータが2進数を扱っていることに関連しています。

「10進数の小数点数の中には、2進数に変換できないものがある」からです。
たとえば、10進数の0.1は、決して2進数で表せません。小数点以下が100桁あっても表せないのです。

・・・(省略)・・・

実際、10進数の0.1を2進数に変換すると、0.000110011・・・(以下1100の繰り返し)という「循環小数」になります。これは、1/3を10進数で表せないのと同じことです。1/3は、0.3333・・・という循環小数になりますよね。

変数dに0.1を格納した時点で、2進数が近似値になってしまったのです。0.1の近似値を100回加えても、結果は10にはなりません。有限な機械であるコンピュータは、無限に続く循環小数を取り扱うことができません。変数のデータ型に応じたビット数に合わせて途中でカットしてしまいます。これによって、0.3333・・・という循環小数を途中でカットして0.333333とした場合に、それを3倍にしてもにはならない(0.999999となる)ことと同じ問題が発生するのです。

※「プログラムはなぜ動くのか」から抜粋

えーと、説明不足であったり、分かりにくいかもしれません・・・その場合は「プログラムはなぜ動くのか」を見てください。


http://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AF%E3%81%AA%E3%81%9C%E5%8B%95%E3%81%8F%E3%81%AE%E3%81%8B-%E2%80%95-%E7%9F%A5%E3%81%A3%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98-%E7%9F%A2%E6%B2%A2-%E4%B9%85%E9%9B%84/dp/4822281019




環境

C:\enjoy_ruby>ruby -v
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]