RubyのNumericとTimeで数値と時間をさまざまな操作・演算・判定:若手エンジニア/初心者のためのRuby 2.1入門(6)(3/4 ページ)
オープンソースのオブジェクト指向プログラミング言語「Ruby」の文法を一から学ぶための入門連載。最新版の2.1に対応しています。今回は、数値/時刻を表現するクラスの使い方、型の変換、基本的な演算・比較、さまざまな用途で使える便利なメソッドなどを解説します。
数値を扱う際の便利なメソッドたち
Numericクラスを継承する各数値クラスには、たくさんの便利なメソッドが定義されています。ここでは、その中からよく使われるものをピックアップして紹介します。
数値を丸めるための4つのメソッド(ceil、floor、round、truncate)
現場でよく使われるのは、数値を丸めるようなメソッドでしょう。一口に「丸める」といっても、切り上げたり、切り捨てたり、四捨五入したり、いくつかの丸め方を考えることができます。以下の表に丸めメソッドの一覧を示します。
メソッド | 挙動 |
---|---|
ceil | 自分と等しいか、自分より大きい整数のうち、最小のものを求める |
floor | 自分と等しいか、自分より小さい整数のうち、最大のものを求める |
round | 自分に最も近い整数を求める(四捨五入) |
truncate | 0から自分までの整数で、自分に最も近い整数を求める |
- ceil
では、ceilの動作を見てみましょう。以下の実行結果が表の説明の通りになっていることを確認してみてください。
[1] pry(main)> 1.6.ceil => 2 [2] pry(main)> 1.4.ceil => 2 [3] pry(main)> -1.6.ceil => -1 [4] pry(main)> -1.4.ceil => -1
- floor
次はfloorです。ceilと同じく、以下の実行結果が表の説明の通りになっていることを確認してみてください。
[1] pry(main)> 1.6.floor => 1 [2] pry(main)> 1.4.floor => 1 [3] pry(main)> -1.6.floor => -2 [4] pry(main)> -1.4.floor => -2
- round
roundも見てみましょう。実行結果が四捨五入になっていることを確認してみてください。ちなみに、1.5のような中央値は、[5]や[6]のように絶対値が大きい方に寄せられます。
[1] pry(main)> 1.6.round => 2 [2] pry(main)> 1.4.round => 1 [3] pry(main)> -1.6.round => -2 [4] pry(main)> -1.4.round => -1 [5] pry(main)> 1.5.round => 2 [6] pry(main)> -1.5.round => -2
- truncate
最後に、truncateの動作を確認しましょう。実行結果が表の説明の通りになっていることを確かめてください。
[1] pry(main)> 1.6.truncate => 1 [2] pry(main)> 1.4.truncate => 1 [3] pry(main)> -1.6.truncate => -1 [4] pry(main)> -1.4.truncate => -1
絶対値を求めるabsメソッド
absメソッドを使うと、絶対値を求めることができます。以下に例を示します。
[1] pry(main)> 42.abs => 42 [2] pry(main)> -42.abs => 42 [3] pry(main)> (-1+1i).abs => 1.4142135623730951
[1]のように正の整数の絶対値は、対象の値そのものなので42が返っています。[2]は負の整数の絶対値を求める例で、この場合はマイナスがとれて42が返ります。
[3]は複素数の絶対値を求めています。数学が苦手な方は、以下の図を見てちょっと復習してみましょう。
(-1+1i)は実部が-1、虚部が1の複素数なので、図のピンクの矢印が(-1+1i)を表す複素数です。複素数の絶対値は、このピンクの矢印の長さに当たります。隣辺の長さがそれぞれ1の直角三角形の斜辺の長さは√2なので、「1.414……」という実数が得られます。
ちなみに、絶対値の2乗を求める「abs2」というメソッドもあります。
[4] pry(main)> -4.abs2 => 16
整数かどうかを判定するinteger?メソッド
数値が整数かどうかを判定するためには、integer?メソッドが便利です。以下の例の[1]では、42は整数なのでtrueを返し、42.0は実数なのでfalseを返しています。
[1] pry(main)> 42.integer? => true [2] pry(main)> 42.0.integer? => false
ゼロかどうかを判定するzero?メソッドとnonzero?メソッド
値がゼロかどうかを判定するメソッドとして、zero?メソッドとnonzero?メソッドがあります。以下にいくつか例を示します。
[1] pry(main)> 0.zero? => true [2] pry(main)> 42.zero? => false [3] pry(main)> 0.nonzero? => nil [4] pry(main)> 42.nonzero? => 42
zero?メソッドは、対象の数値がゼロか否かでtrueかfalseを返します。そのため、[1]の返り値はtrueで、[2]の返り値はfalseとなっています。
nonzero?メソッドは、対象の数値がゼロならnilを、そうでないなら数値そのものを返します。そのため、[3]の返り値はnilで、[4]の返り値は42となっています。
最大公約数/最小公倍数を求める3つのメソッド(gcd、lcm、gcdlcm)
Integerクラスには、最大公約数を求めるgcdメソッド、最小公倍数を求めるlcmメソッド、それら両方を一度に求めるgcdlcmメソッドが定義されています。以下に例を示します。
[1] pry(main)> 24.gcd(4) => 4 [2] pry(main)> 24.lcm(4) => 24 [3] pry(main)> 24.gcdlcm(4) => [4, 24]
24と4の最大公約数は4なので、[1]の結果からgcdメソッドが正しく最大公約数を返していることが分かります。同じく[2]では、最大公倍数である24が返っています。また、[3]の結果から、gcdlcmメソッドは最大公約数と最小公倍数のペアを配列で返すことが分かります。
カッコ良くループを回すための4つのメソッド(upto、downto、times、step)
- upto
数値クラスに定義されているuptoメソッドを使うと、ちょっとオシャレにループを書くことができます。さっそく例を見てみましょう。
[1] pry(main)> 5.upto(10) { |n| p n } 5 6 7 8 9 10 => 5
この例は、5から10までの数値を、1ずつ増やしながらpメソッドで表示していく例です。uptoメソッドは、引数に与えた数値まで1ずつ値を増やしながら、同じく引数として与えられたブロックを繰り返し実行します。カウントアップされている値は、ブロック引数を通して使えます。
- downto
uptoメソッドがあるなら、もちろんdowntoメソッドもあります。以下にdowntoメソッドの利用例を示します。
[1] pry(main)> 10.downto(5) { |n| p n } 10 9 8 7 6 5 => 10
この例は、10から5までの数値を、1ずつ減らしながらpメソッドで表示していく例です。downtoメソッドは、引数に与えた数値まで1ずつ値を減らしながら、同じく引数として与えられたブロックを繰り返し実行します。カウントダウンされている値は、ブロック引数を通して使えます。
- times
場合によっては、単純に「5回ループを回したい」というような場合もあるでしょう。uptoメソッドを使って「1.upto(5)」と書けば目的を達成できますが、timesメソッドを使えばよりスマートに記述できます。以下の例を見てください。
[1] pry(main)> 5.times { |n| p n } 0 1 2 3 4 => 5
timesメソッドの場合、カウントアップされるインデックスが0から始まることに注意してください。
- step
uptoメソッドやdowntoメソッドをより一般的にしたものがstepメソッドです。利用例を見てみましょう。
[1] pry(main)> 5.step(20, 2) { |n| p n } 5 7 9 11 13 15 17 19 => 5
stepメソッドの第1引数に上限を、第2引数にはループの各段階でいくつ値を増やすかを指定します。この例だと、「5から始まり、2ずつ増やしてループを実行、上限の値は20」という意味になります。そのため、画面に出力される値は5、7、9、と2つ飛ばしになり、19が最後に出力される値となっています。
Copyright © ITmedia, Inc. All Rights Reserved.