roy > naoya > 基礎プログラミングI·情報検索 > (5)値の型変換
これまでgetsメソッドを使ってコンピュータに数字を入力したり、最初からプログラムの中にsum = 0というように初期値として数字を与えていた。特に問題なくこれで利用できていたが、問題点に気づいた人がいたかもしれない。これまでのプログラムでは実は小数を含む実数を取り扱うことができなかったのである。
これは前回のレポート課題で作成したプログラムに、アルバイト時間として5.5や4.2など小数を含む数値を代入してみれば容易に確認できる。
#!/usr/koeki/bin/ruby a = 5 b = 2 c = a / b p c
pメソッドは久しぶりの登場だが、変数内の値を表示するメソッドである。このプログラムを実行すると、2.5という結果が表示されるような気がする。しかし、実行結果はそうはならない。
irsv{naoya}% ruby value.rb[Return] 2
結果は2となっている。なぜだろうか?
我々は「123」は整数、「10.5」は実数(整数+小数)、「プログラミング」は文字列であると直感的に理解できる。しかしコンピュータは理解することができない。このため取り扱っている値が整数なのか実数なのか文字列なのかを明確に指示する必要がある。
値の型について
a=10とプログラム中に記載した場合、aに10を代入するという意味になる。ではb=10.0と入力した場合はどうなるだろうか。c=3とし、d=a/c、e=b/cとした場合に何が異なるだろうか。まずは予想をしてから以下のプログラム(value.rb)を実行してみよう。
#!/usr/koeki/bin/ruby a = 10 b = 10.0 c = 3 d = a / c e = b / c p d p e
これを実行すると以下のようになる。
irsv{naoya}% ruby value.rb[Return] 3 #->p dの出力結果 3.333333333 #->p eの出力結果
a = 10とした場合、aに代入されている値は整数であると判断される。このため3で割っても小数点以下が切り捨てとなり、答えは3になっている。一方、b = 10.0とするとbに代入されている値は小数点以下を含む実数であると判断される。これにより3で割った答えにも小数点以下の値が含まれる。
初期値を与える際の型指定の方法
整数と実数を初期値として与える際の注意を見てきたが、今度は文字列を初期値として与える方法について復習しよう。具体的には以下のvalue2.rbを実行してみる。余裕のある人は実行結果を確認した後でb = "200"をb = 200に変更して再度実行してみる。
#!/usr/koeki/bin/ruby a = "100" b = "200" c = "Ru" d = "by" e = a + b f = c + d p e p f
制限時間は10分。出席点は2点。提出要領は下記の通り。
Tips:emacsでの日本語入力のオンオフはCtrl-oです
Tips:Mewによるメールの送り方はMewコマンドを参照
キーボードからの入力を読み込むメソッドとしてgetsメソッドを使用してきた。これまではgets.chomp!.to_iというように後ろにchomp!.to_iをつけて利用してきたが、実はchomp!もto_iも特定の働きを持つメソッドである。
getsではなくgets.chomp!.to_iとしてきたのは、今回の授業で取り上げた値の型が関連する。getsメソッド、chomp!メソッド、to_iメソッドの働きについてここで確認してみよう。
getsメソッドはキーボードからの入力を文字列として取得する。このため、ユーザーが数字の100(ひゃく)のつもりで入力しても文字列の100(いちぜろぜろ)として扱われてしまう。
さらに言えば、キーボードから入力する場合、入力後に確定のために[Return]キーを押す。[Return]キーは改行をあらわす\nとしてコンピュータ内では取り扱われる。このため、数字の100(ひゃく)を入力したつもりでも、コンピュータが受け取るデータは100\n(いちぜろぜろバックスラッシュエヌ)となっている。
そこで、getsメソッドにchomp!メソッドをつけることで、まずバックスラッシュエヌを取り除いている。その後、to_iメソッドをつけることで、文字列を整数に変換している。
getsメソッドについて
getsメソッドはキーボードからの入力を文字列として取得する。入力した値を整数として扱う場合はchomp!.to_iをつける。キーボードから100[Return]を入力した場合に変数に代入される値を確認しよう。
to_iは値の型を整数に変換するメソッドであったが、実数に変換するメソッドや文字列に変換するメソッドもある。
値の型変換メソッド
a = 10.0のようにプログラム内に具体的に値を記述できる場合は、プログラム作成時に配慮すれば、以後値の型を気にしなくても良いが、キーボードからの入力を受け取る場合はこれらのメソッドを使って値の型を指定しなければ全て文字列扱いとなってしまう。
これらの働きをプログラムの実行を通して確認してみよう(form.rb)。
#!/usr/koeki/bin/ruby print "1つ目の数字を入力してください:\n" a = gets.chomp! #=>to_iがついていないことに注意 print "2つ目の数字の入力してください:\n" b = gets.chomp! #=>to_iがついていないことに注意 c = a + b p c d = a.to_i + b.to_i p d e = a.to_f + b.to_f p e f = a.to_s + b.to_s p f
これを実行すると以下のようになる。
irsv{naoya}% ruby form.rb[Return] 1つ目の数字を入力してください: 100[Return] 2つ目の数字の入力してください: 45[Return] "10045" 145 145.0 "10045"
変換メソッドをつけずにa+bとした場合、getsは文字列として値を取り込むため、「100(いちぜろぜろ)」と「45(よんご)」の2つの値が入力されたことになり、これらの足し算をすると文字列が結合される。to_iやto_fをつけると数字として扱われることがわかる。
これらの型変換メソッドは、gets.chomp!.to_iのようにgets.chomp!に続けて使う以外に、このプログラムのように変数.to_iのように使用することもできる。
to_iやto_f、to_sの各メソッドを使用する場所について注意しよう。なんでもかんでもgets.chomp!.to_iとするとうまくプログラムが動かない場合がある。次のプログラムregi.rbで確認しよう。
#!/usr/koeki/bin/ruby sum = 0 while true print "金額を入力(終了はquit):\n" price = gets.chomp!.to_i if price == "quit" then break end sum += price end printf ("合計%d円です。\n", sum)
このプログラムはwhile trueを使用しており、while-end内にif文でbreakをつけることで繰り返しから抜けるように書かれている。if文ではpriceに代入された値がquitの場合にbreakせよと書いており、ユーザーが金額を入力する代わりにquitと入力すれば繰り返しから抜ける。では、実行結果を見てみよう。
irsv{naoya}% ruby regi.rb[Return] 金額を入力(終了はquit): 198[Return] 金額を入力(終了はquit): 298[Return] 金額を入力(終了はquit): quit[Return] 金額を入力(終了はquit):
quitを入力しても終了しないことがわかる。このプログラムは永久に終了しない。なお、プログラムを実行したがどうしても止まらないという状況になった場合はCtrl-cで強制終了させることができる。
終了しない原因はprice = gets.chomp!.to_iにある。to_iがあるので、入力した値を整数に変換してからpriceに代入する。このためquitも整数に変換してpriceに代入している。priceなどのアルファベットは整数に変換すると0になるこのため、このプログラムではpriceに代入された値がquitであるというif文に記載された条件を満たすことが永久になくなってしまう。
正しく終了するためにはto_iの位置を変更する必要がある。gets.chomp!.to_iをgets.chomp!に修正し、to_iをsum += price.to_iの位置につけ、sumに金額を加算する際に整数に変換すればうまく動くようになる。
#!/usr/koeki/bin/ruby sum = 0 while true print "金額を入力(終了はquit):\n" price = gets.chomp! if price == "quit" then break end sum += price.to_i end printf ("合計%d円です。\n", sum)
irsv{naoya}% ruby regi.rb[Return] 金額を入力(終了はquit): 198[Return] 金額を入力(終了はquit): 298[Return] 金額を入力(終了はquit): quit[Return] 合計496円です。
値の型変換メソッドをつける位置について
printとprintfの使い分けはだいぶ理解できて来ただろうか。printは""内に入力されたメッセージをそのまま出力するメソッドである。一方、printfは変数内に代入されている値を出力する場合に""内に%dをいれ""の後ろに具体的に変数を指定することで、表示をおこなうメソッドであった。
ここで%dとは果たして何を意味しているのであろうか。実は%dは%とdに分割することができる。厳密に言うと、%の位置に、""の後ろで指定された変数内の値を表示する。dは表示するときの形式(書式制御文字と呼ぶ)である。dはdecimal(10進数)の頭文字で、%dとした場合は変数内の値を「10進整数」で表示せよという意味になる。
我々が日常的に使用している数字は10進数と呼ばれるもので、0〜9の10種類の値を使用する。一方で、コンピュータの世界では0と1のみ使用する2進数、0、1、〜、9、a、b、c、d、e、fの16種類の数字を使用する16進数が利用されている。
printfで結果を出力する場合には、変数内の値を10進整数で表示する以外に、2進数や16進数、小数点を含む実数で表示することもできる。これにより、計算過程では.to_fをつけて計算を行ってきたが、結果を表示するときは小数点以下を切り捨てて整数で表示するというようなことも可能になる。主な書式制御文字は以下の通り。
printfの書式制御文字について
format.rb
a = 100 printf ("10進整数だと%d\n", a) printf ("2進整数だと%b\n", a) printf ("16進整数だと%x\n", a) printf ("浮動小数点数だと%f\n", a) printf ("文字列だと%s\n", a)
irsv{naoya}% ruby format.rb[Return] 10進整数だと100 2進整数だと1100100 16進整数だと64 浮動小数点数だと100.000000 文字列だと100
%fを指定した場合、デフォルトで小数点以下第6位まで出力される。
%と書式制御文字の間に出力幅を指定する整数を書くことができる。%4dのように「4」と入れると、結果を4桁で表示せよということになる。25(2桁)や137(3桁)の場合には、左側にそれぞれスペースが2つ、1つ空くことになる。整数の左にマイナスをつけると左づめになる。fの場合は6.2のように小数で指定する。これは全体の桁数が6桁で、小数点以下が2桁であるという指定になる。%fを桁の指定をせずに使用すると標準の6桁で表示される。
整数を入れると右づめになる printf ("答えは%6dです\n", a) #=>___100 整数にマイナスをつけると左づめになる printf ("答えは%-6dです\n", a) #=>100___ %fでは全体の桁、小数部の桁の順に指定する ここでは小数を含めて全体が6桁、小数は3桁になっている printf ("答えは%6.3fです\n", a) #=>_12.500
printfによる桁揃え出力
前回作成したkadai2.rbについて以下の改良を施しなさい(kadai3.rb)。
プログラムの変更点はこの2つであるが、難しい場合は一方でも構わない。余裕がある人は、これらに加えて平均のアルバイト時間に応じて適宜メッセージを出す(if文)など、いろいろなことに挑戦しても良い。
1番に比べて2番は難しい。平均時間は合計÷日数で求められるが、日数(数字を入力した回数)をどうやって求めるのかがポイントとなる。前回の授業のサンプルプログラムをよく眺めてみよう。
Tips:emacsでの日本語入力のオンオフはCtrl-oです
Tips:ktermでのプログラムの実行結果をメールに貼り付けるには、コピーしたい箇所をマウスで選択し、emacs(Mew)上でマウスの真ん中ボタンをクリックする
Tips:Mewによるメールの送り方はMewコマンドを参照