連載
» 2014年07月29日 18時00分 公開

RubyのNumericとTimeで数値と時間をさまざまな操作・演算・判定若手エンジニア/初心者のためのRuby 2.1入門(6)(2/4 ページ)

[著:麻田優真、監修:山根剛司,株式会社アジャイルウェア]

型の変換

数値から数値へ

 場合によっては、明示的に数値の型を変換したいこともあるでしょう。その場合、「to_x」(xはiやfなどの型を表すアルファベット)という形式のメソッドを使うことで相互に変換できます。以下にいくつか例を示します。

[1] pry(main)> 42.to_f
=> 42.0
[2] pry(main)> 42.to_r
=> (42/1)
[3] pry(main)> 42.to_c
=> (42+0i)
[4] pry(main)> 0.25.to_r
=> (1/4)

 [1]〜[3]は、整数から別の型に変換する例です。[1]は整数から実数に、[2]は整数から有理数に、[3]は整数から複素数に変換しています。[4]は実数を有理数に変換する例です。

 また、情報量の多い型から情報量の少ない型への変換では、元の型だと保持できていた情報が落ちてしまうことがあります。以下にいくつか例を示しましょう。

[5] pry(main)> 42.195.to_i
=> 42
[6] pry(main)> 1/3r.to_f
=> 0.3333333333333333

 [5]は実数を整数に変換していますが、整数は小数点以下の情報を保持できないので、単純に切り捨てられてしまいます。[6]は有理数を実数に変換していますが、その結果が循環小数となっているので、ある意味で情報が落ちているといえます。

文字列から数値へ

 現場でよく行われるのは文字列から数値への変換です。これも「to_x」(xは型を表すアルファベット)メソッドを使うことで直感的にできます。

[8] pry(main)> "42".to_i
=> 42
[9] pry(main)> "42".to_f
=> 42.0
[10] pry(main)> "0.25".to_f
=> 0.25
[11] pry(main)> "0.25".to_r
=> (1/4)
[12] pry(main)> "42.195".to_i
=> 42

 [8]は文字列を整数に変換しており、[9]は整数形式で表記されている文字列を実数に変換しています。[10]は実数形式で表記されている文字列を実数に変換しています。

 また、[11]のように実数形式となっている文字列を有理数に変換することも可能です。ただし、[12]のように実数形式の文字列を「to_i」を使って整数に変換した場合、小数点以下の情報が落ちてしまうので注意してください。

 当然ながら、数値に変換しようとしてもできないような文字列もあります。そのような場合の例をいくつか見てみましょう。

[13] pry(main)> "Alice".to_i
=> 0
[14] pry(main)> "ありす".to_i
=> 0
[15] pry(main)> "42".to_i
=> 0
[16] pry(main)> "ABC".to_i
=> 0
[17] pry(main)> "0xABC".to_i
=> 0

 以上の例はどれも変換に失敗しています。[15]のように全角数字も変換できませんし、[17]のように16進数表記されている文字列も、直感的にできそうですが実際には失敗します。to系メソッドは失敗した場合0を返します。

 これは本当にわなです。トラップです。変換に失敗してしまったという事実を握りつぶしてしまう上、0という数値を返してしまうため、失敗したかどうかをチェックすることもできません。

 そこで、Integer()やFloat()といった、明示的に数値オブジェクトを生成するメソッドを使うことで、変換に失敗した場合に例外を投げることができます。

[18] pry(main)> Integer("42")
=> 42
[19] pry(main)> Integer("Alice")
ArgumentError: invalid value for Integer(): "Alice"
from (pry):18:in `Integer'

 [18]では、"42"という文字列を整数に変換できるので、整数である42が返り値として得られます。[19]では「ArgumentError」という例外が投げられ、"Alice"という文字列は正しくない(整数に変換できない)引数だよと教えてくれています。

 例ではpry上で確認しているので例外が出た後も続けてRubyのコードを入力できますが、スクリプトとして動かしている場合、例外が投げられた時点でプログラムは停止します。ですので、実際には投げられた例外をキャッチして適切に処理する必要があるでしょう。例外の仕組みと例外処理については、以降の連載であらためて解説します。

補足「変換できない場合のto系メソッドの挙動」

 先ほど、変換できないときに0を返す挙動はわなであると主張しましたが、この事実を知っていれば大きな問題になりません。コードが煩雑になることを避けるために、時には変換に失敗した事実を握りつぶしてしまった方がいい場合もあります。

 ただ、筆者の経験から、このような挙動は「一見うまく動いているけれど、実はバグをはらんでいる」ようなコードを書いてしまう原因となってしまうことあるので、特に初学者は注意すべきポイントだと思います。


Rubyにおける基本的な数値の演算

 ここでは、基本的な演算について例を示しながら解説します。違う型同士の演算は、原則として情報量の少ない方の型の数値が、情報量の多い方の型に変換されてから演算されます。例えば、整数と実数ならば、整数が実数に変換された上で演算が行われます。以下にいくつか例を示しましょう。

符号の反転

 単項演算子「-」を使うことで、数値の符号を反転できます。以下の例は、[1]で変数answerに整数42を代入し、[2]で「-」で符号を反転させています。[3]のように、2回符号を反転させると正の数に戻ります。

[1] pry(main)> answer = 42
=> 42
[2] pry(main)> -answer
=> -42
[3] pry(main)> --answer
=> 42

加減算

 これまで何気なく加減算を行ってきたように、他のプログラミング言語同様、「+」および「-」演算子を用い、その挙動は直感的です。以下にいくつか例を示しましょう。

[1] pry(main)> 1 + 1
=> 2
[2] pry(main)> 1 - 1
=> 0
[3] pry(main)> 1.0 + 1
=> 2.0
[4] pry(main)> 1 + 1/3r
=> (4/3)

 [1]と[2]は整数同士の加算と減算を行っています。整数同士の演算であるため、その返り値は整数となっています。[3]は実数と整数の加算です。この場合、実数の方が情報量が多いので演算結果は実数となっています。[4]も同様に、より情報量の多い有理数に合わせて演算結果が有理数となっています。

乗算・累乗

 乗算も、他のプログラミング言語の経験があれば、おおむね直感的でしょう。乗算には「*」演算子を使います。いくつか例を見てみましょう。

[1] pry(main)> 21 * 2
=> 42
[2] pry(main)> 2.1 * 2.0
=> 4.2
[3] pry(main)> 2.1 * 2
=> 4.2
[4] pry(main)> 2 ** 2
=> 4
[5] pry(main)> 2 ** 0.5
=> 1.4142135623730951

 [1]は整数同士の乗算、[2]は実数同士の乗算の例です。また、[3]は実数と整数の乗算ですが、この場合もより情報量の多い実数に合わせられて、4.2という値が返ってきます。

 「**」演算子を使うことで累乗を求めることもできます。[4]は2の2乗ということで、4という整数が返ります。[5]のように、乗じる値に実数を使うこともできます。ある値の0.5乗は平方根をとることと等価なので、この場合は「1.41……」という実数が返ります。

除算・剰余

 除算には「/」演算子を使います。また、剰余を求めるには「%」演算子を使います。以下にいくつかの例を挙げます。

[1] pry(main)> 84 / 2
=> 42
[2] pry(main)> 3 / 2
=> 1
[3] pry(main)> 8.4 / 2.0
=> 4.2
[4] pry(main)> 8.4 / 2
=> 4.2
[5] pry(main)> 3.0 / 2
=> 1.5
[6] pry(main)> 5 % 2
=> 1

 [1]および[2]は整数同士の除算ですが、整数同士の場合、[2]のように割り切れない場合でも得られる答えは整数です。

 [3]は実数同士の除算で、[4]は整数と実数の除算です。[4]のように、除算においても整数は実数として扱われ、その返り値は実数となっています。

 [2]のような除算で実数の結果が欲しい場合、[5]のようにどちらかの値を実数とすることで、期待する1.5という値が得られます。

 [6]は剰余を求める例です。「5 ÷ 2」の場合、商が2、剰余が1となるので、[6]の演算結果は1となっています。

数値の比較

 比較も演算と同様、違う型同士だと、原則として情報量の少ない方の型の数値が、情報量の多い方の型に変換されてから比較されます。いくつか例を見てみましょう。

[1] pry(main)> 42 == 42
=> true
[2] pry(main)> 42.0 == 42
=> true
[3] pry(main)> 0.3333 < 1/3r
=> true  

 [1]は整数同士の比較で、右辺も左辺も42で等しいのでtrueを返しています。[2]は実数と整数の比較ですが、整数が実数として比較されるため、返り値はtrueです。[3]は実数と有理数を比較していますが、右辺の「1/3」(3分の1)は小数表記すると「0.33333……」という無限小数となるため、この比較の返り値はtrueとなります。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。