Java道|Mathクラスで広がる数値処理

四則演算だけでは届かない計算も、Mathクラスならすぐ扱える。
Javaに用意された計算道具を使いこなせば、数値処理はもっとスマートになる。

Javaで数値を扱うとき、最初は足し算、引き算、掛け算、割り算といった四則演算を学びます。

たとえば、隊士の点数を合計したり、人数を掛け算したり、残りの個数を引き算したりする処理です。

しかし、プログラムを書いていくと、四則演算だけでは少し書きにくい計算も出てきます。

たとえば、次のような処理です。

やりたいこと
2つの数のうち大きいほうを知りたい72点と88点なら88点を選ぶ
2つの数のうち小さいほうを知りたい最低点を調べる
マイナスを正の大きさとして扱いたい-7 を 7 として扱う
平方根を求めたい25 の平方根を求める
累乗を求めたい2 の 3乗を求める
ランダムな数を出したい1〜6 の目をランダムに出す

こうした計算をすべて自分で一から書くのは大変です。

そこで登場するのが Math クラスです。

Math クラスは、Javaが用意している数値計算用の便利なクラスです。
最大値、最小値、絶対値、平方根、累乗、乱数など、よく使う計算をメソッドとしてまとめて持っています。

鬼滅の刃でたとえると、Math クラスは鬼殺隊本部が用意している「計算道具箱」です。

隊士の点数を比べる道具。
距離の差を正の値として見る道具。
特殊な計算を一瞬で行う道具。
訓練の抽選やランダムな出目を作る道具。

こうした計算道具を、必要な場面で取り出して使えるようになると、Javaの数値処理はかなり書きやすくなります。

Mathクラスとは何か

Math クラスは、数値計算に役立つ機能をまとめたクラスです。

Javaでは、普通の計算なら演算子で書けます。

計算書き方
足し算a + b
引き算a - b
掛け算a * b
割り算a / b

ただし、次のような計算は、演算子だけで書くよりも、用意されたメソッドを使ったほうが分かりやすいです。

やりたいことMathクラスのメソッド
大きいほうを返すMath.max()
小さいほうを返すMath.min()
絶対値を返すMath.abs()
平方根を返すMath.sqrt()
累乗を返すMath.pow()
乱数を返すMath.random()

鬼滅の刃でたとえると、普通の四則演算は、隊士が自分で行う基本訓練です。
一方、Math クラスは、本部に用意された専用の計算道具です。

「どちらの点数が高いか」
「差の大きさはいくつか」
「ランダムに任務番号を出す」

こうした処理を、メソッド名で分かりやすく呼び出せるのが Math クラスの便利なところです。

Mathクラスはクラスメソッドで使う

Math クラスの大きな特徴は、多くのメソッドがクラスメソッドとして用意されていることです。

クラスメソッドは、オブジェクトを作らなくても、クラス名を使って呼び出せるメソッドです。

Math クラスを使うときは、次のように書きます。

Math.メソッド名(引数)

たとえば、2つの値のうち大きいほうを調べるなら、次のように書きます。

Math.max(8, 15)

この結果は 15 です。

ここでは、new Math() のように Math オブジェクトを作っていません。

種類呼び出し方
インスタンスメソッドオブジェクト名.メソッド名()str.length()
クラスメソッドクラス名.メソッド名()Math.max(8, 15)

これは、以前学んだ Integer.parseInt() と似ています。

Integer.parseInt("25")

Integer.parseInt() も、Integer クラス名を使って直接呼び出すクラスメソッドでした。

Math.max() も同じように、Math クラス名を使って呼び出します。

鬼滅の刃でたとえると、Math.max() は、特定の隊士が持つ個人技ではありません。
鬼殺隊本部の計算道具箱にある共通機能です。

だから、隊士オブジェクトを作るのではなく、Math という本部の道具箱から直接 max() を取り出して使うイメージです。

Mathクラスの主なメソッド

Math クラスには、数値計算に役立つメソッドがたくさんあります。

代表的なものを整理すると、次のようになります。

メソッド名機能鬼滅の刃でたとえると
abs絶対値を返す距離や差の大きさだけを見る
ceil指定した値以上の最も小さい整数値を返す少しでも超えたら上の段へ切り上げる
cosコサイン値を返す角度を使う特殊計算
floor指定した値以下の最も大きい整数値を返す小数部分を下へ切り下げる
max2つの値のうち大きいほうを返す高い点数の隊士を選ぶ
min2つの値のうち小さいほうを返す低い点数を確認する
pow累乗した結果を返す力を何段階も高める
random0.0以上1.0未満の乱数を返す任務の抽選札を引く
rint最も近い整数値を返す近い整数へ丸める
sinサイン値を返す角度を使う特殊計算
sqrt平方根を返す面積や距離計算に使う
tanタンジェント値を返す角度を使う特殊計算

この中でも、学習の初期段階で特によく使いやすいのは、次のあたりです。

よく使うメソッドまず押さえたい役割
max()大きいほうを選ぶ
min()小さいほうを選ぶ
abs()絶対値を求める
sqrt()平方根を求める
pow()累乗を求める
random()乱数を作る

まずは、全部を一度に覚えようとしなくて大丈夫です。

「Math クラスは数値計算の道具箱」
「必要な計算に合わせてメソッドを選ぶ」

この感覚を持つことが大切です。

まずはmax()メソッドから見る

Math クラスの中でも、最初に分かりやすいのが max() メソッドです。

max() は、2つの値のうち大きいほうを返します。

たとえば、次のように使います。

Math.max(5, 10)

この結果は 10 です。

呼び出し結果
Math.max(5, 10)10
Math.max(72, 88)88
Math.max(100, 45)100

鬼滅の刃でたとえると、2人の隊士の訓練点を比べて、高い点数のほうを選ぶ技です。

たとえば、水月が72点、炎真が88点だった場合、Math.max(72, 88) は 88 を返します。

このように、if 文を使って比較を書くこともできますが、単純に大きいほうを知りたいだけなら、Math.max() を使うと短く分かりやすく書けます。

Math.max() の使い方を確認する

実際のプログラムで、Math.max() の使い方を確認していきましょう。

ファイル名:Sample5.java

import java.io.*;

class Sample5
{
    public static void main(String[] args) throws IOException
    {
        // キーボード入力の準備をする
        BufferedReader br =
            new BufferedReader(new InputStreamReader(System.in));

        // 2つの整数を入力してもらう
        System.out.println("2人の隊士の訓練点を入力してください。");
        String str1 = br.readLine();
        String str2 = br.readLine();

        // 文字列を整数に変換する
        int num1 = Integer.parseInt(str1);
        int num2 = Integer.parseInt(str2);

        // 高いほうの点数を調べる
        int ans = Math.max(num1, num2);

        // 結果を表示する
        System.out.println("高い訓練点は " + ans + " 点です。");
    }
}

このプログラムでは、2人の隊士の訓練点を入力します。

たとえば、次のように入力したとします。

2人の隊士の訓練点を入力してください。
72
88

表示結果は次のようになります。

高い訓練点は 88 点です。

このプログラムで大切なのは、入力、変換、比較の流れです。

最初に br.readLine() で入力を受け取ります。
ただし、入力された 72 や 88 は、最初は String 型の文字列です。

そこで、Integer.parseInt() を使って int 型の整数に変換します。

int num1 = Integer.parseInt(str1);
int num2 = Integer.parseInt(str2);

そのあとで、Math.max() を使って大きいほうを調べます。

int ans = Math.max(num1, num2);

鬼滅の刃でたとえると、2人の隊士が訓練点の札を提出し、その札を数値として読み取り、本部の計算道具で高い点数を選んでいる流れです。

プログラムの流れを整理する

Sample5.java の処理を順番に整理すると、次のようになります。

順番処理内容説明
1BufferedReader を用意するキーボード入力の準備をする
2br.readLine() で2つの入力を受け取る入力された点数は最初は文字列
3Integer.parseInt() で変換する計算できる整数にする
4Math.max(num1, num2) を呼び出す2つの値のうち大きいほうを調べる
5結果を表示する高い訓練点を画面に出す

ここから分かるのは、Math クラスは単独で使うだけではなく、他のクラスと組み合わせて使うことが多いということです。

使っているクラス役割
BufferedReader入力を受け取る
InputStreamReader入力を文字として扱えるようにする
Integer文字列を整数に変換する
Math数値計算を行う
System結果を画面に表示する

Javaの実用的なプログラムでは、このように複数のクラスライブラリを組み合わせて処理を作ります。

鬼滅の刃でたとえると、伝令札を受け取る係、数字へ読み替える係、点数を比較する計算係、結果を報告する係が連携しているようなものです。

Math.max()を使うと比較が短く書ける

2つの値の大きいほうを求める処理は、if 文でも書けます。

たとえば、考え方としては次のような流れです。

int ans;

if (num1 > num2)
{
    ans = num1;
}
else
{
    ans = num2;
}

これでも問題ありません。

ただ、単純に「2つのうち大きいほうを返す」だけなら、Math.max() を使ったほうが短く書けます。

int ans = Math.max(num1, num2);
書き方特徴
if 文で比較する条件分岐の流れが見える
Math.max() を使う大きいほうを求める意図が一目で分かる

鬼滅の刃でたとえると、if 文で一つずつ判定するのは、隊士の点数を手作業で比べるようなものです。
Math.max() は、本部の計算道具に2つの点数を入れると、高いほうをすぐ返してくれるイメージです。

max()はオーバーロードされている

Math.max() は、1種類だけではありません。

int 型どうしを比べる max() もあります。
double 型どうしを比べる max() もあります。

これは、以前学んだオーバーロードです。

オーバーロードとは、同じ名前のメソッドでも、引数の型や個数が違えば複数定義できる仕組みです。

Math.max() では、引数の型に応じて適切なメソッドが選ばれます。

Math.max(5, 10);
Math.max(12.5, 20.5);
呼び出し例使われる考え方
Math.max(5, 10)int 型どうしの比較
Math.max(12.5, 20.5)double 型どうしの比較

鬼滅の刃でたとえると、同じ「高いほうを選ぶ技」でも、整数の訓練点を比べる型と、小数を含む呼吸精度を比べる型が用意されているようなものです。

同じ max() という名前で使えるので、使う側はとても分かりやすくなります。

min()メソッドもセットで覚える

max() とあわせて覚えたいのが min() です。

min() は、2つの値のうち小さいほうを返します。

Math.min(5, 10)

この結果は 5 です。

メソッド役割結果
max()大きいほうを返すMath.max(5, 10)10
min()小さいほうを返すMath.min(5, 10)5

鬼滅の刃でたとえると、max() は高い訓練点を見つける技です。
min() は低い訓練点を見つける技です。

高い点を表彰したいときは max()。
低い点を見つけて再訓練の対象を確認したいときは min()。

このように、max() と min() は比較処理の基本セットとして覚えると便利です。

abs()で絶対値を求める

abs() は、絶対値を求めるメソッドです。

絶対値とは、数の符号を外した大きさです。

たとえば、-7 の絶対値は 7 です。
5 の絶対値は 5 のままです。

Math.abs(-7)

この結果は 7 です。

呼び出し例結果
Math.abs(-12)12
Math.abs(5)5
Math.abs(0)0

abs() は、差の大きさを調べたいときによく使います。

たとえば、水月の点数が72点、炎真の点数が88点だったとします。

差を計算すると、72 - 88 は -16 になります。
でも、点数差として知りたいのは 16 点差です。

このようなときに abs() を使うと、符号に関係なく差の大きさを求められます。

鬼滅の刃でたとえると、どちらが上か下かではなく、2人の隊士の実力差がどれだけ離れているかを見るための技です。

sqrt()で平方根を求める

sqrt() は、平方根を求めるメソッドです。

Math.sqrt(25)

この結果は 5.0 です。

平方根とは、ある数を2回掛けたときに元の数になる値です。

たとえば、5 × 5 = 25 なので、25 の平方根は 5 です。

呼び出し例結果
Math.sqrt(9)3.0
Math.sqrt(16)4.0
Math.sqrt(25)5.0
Math.sqrt(2)1.414...

sqrt() の戻り値は double 型です。

結果が整数のように見える場合でも、3.0 や 5.0 のように double 型として返ります。

鬼滅の刃でたとえると、正方形の修練場の面積から、一辺の長さを求めるような計算です。
面積が25なら、一辺は5という感覚です。

pow()で累乗を求める

pow() は、累乗を求めるメソッドです。

Math.pow(2, 3)

この結果は 8.0 です。

これは、2 の 3乗、つまり 2 × 2 × 2 を意味します。

呼び出し例意味結果
Math.pow(2, 3)2の3乗8.0
Math.pow(10, 2)10の2乗100.0
Math.pow(5, 2)5の2乗25.0

pow() も戻り値は double 型です。

鬼滅の刃でたとえると、呼吸の力を何段階も重ねて高めるような計算です。

2の3乗なら、2の力を3回重ねるイメージです。

random()で乱数を使う

Math クラスの中でも、楽しく実用的なのが random() です。

random() は、0.0以上1.0未満の乱数を返します。

Math.random()

ここで大切なのは、返ってくる値がそのまま整数ではないことです。

メソッド返す範囲
Math.random()0.0以上1.0未満の double 型の値

たとえば、次のような値が返る可能性があります。

例:

0.10
0.45
0.92

このままだと、サイコロの目のような 1〜6 の整数にはなりません。

そこで、範囲を広げて、整数に変換し、最後に1を足します。

int num = (int)(Math.random() * 6) + 1;

この式によって、1〜6 の整数を作れます。

意味
Math.random()0.0以上1.0未満の小数を作る
Math.random() * 60.0以上6.0未満に広げる
(int)(...)小数部分を切り捨てる
+ 11〜6 の範囲にする

鬼滅の刃でたとえると、訓練内容を決める抽選札をランダムに引くようなものです。

0〜5 の札ではなく、1〜6 の札にしたいので、最後に + 1 して範囲を整えます。

random()で1〜6を作る流れ

random() の変換は少し分かりにくいので、表で見てみましょう。

Math.random() の値× 6 の結果intに変換後+1 の後
0.100.6001
0.452.7023
0.925.5256

Math.random() は 1.0 未満なので、Math.random() * 6 は 6.0 未満です。

そのため、int に変換すると、0〜5 のどれかになります。

最後に 1 を足すことで、1〜6 の範囲になります。

段階範囲
Math.random()0.0以上1.0未満
Math.random() * 60.0以上6.0未満
(int)(Math.random() * 6)0〜5
(int)(Math.random() * 6) + 11〜6

この考え方は、ゲーム、抽選、ランダム表示などでよく使います。

ceil()とfloor()の違い

Math クラスには、小数を扱うためのメソッドもあります。

ceil() と floor() です。

メソッド機能
ceil()指定した値以上の最も小さい整数値を返す
floor()指定した値以下の最も大きい整数値を返す

少し言葉が難しいですが、感覚としては次のように考えると分かりやすいです。

メソッドイメージ
ceil()切り上げ
floor()切り下げ

たとえば、次のようになります。

呼び出し例結果
Math.ceil(3.2)4.0
Math.floor(3.8)3.0

ceil() は、3.2 より小さくならない整数方向へ進むので 4.0 になります。
floor() は、3.8 より大きくならない整数方向へ進むので 3.0 になります。

鬼滅の刃でたとえると、補給物資を箱単位で数えるときに、少しでも余りが出るなら箱を1つ増やすのが ceil() です。
逆に、小数部分を切り捨てて確定分だけ見るのが floor() です。

図:Mathクラスは計算道具箱

↓クリックすると拡大表示されます。

この図が示していること

この図では、Math クラスを数値計算の道具箱として表しています。

道具箱の中には、max()、min()、abs()、sqrt()、pow()、random() などの計算用メソッドが入っています。

max() は大きい値を返し、min() は小さい値を返します。
abs() は絶対値、sqrt() は平方根、pow() は累乗、random() は乱数を返します。

ここから分かるのは、Math クラスはひとつの計算だけを行うクラスではなく、さまざまな数値処理に使える便利なメソッドをまとめたクラスだということです。

図:random()で1〜6の整数を作る流れ

↓クリックすると拡大表示されます。

この図が示していること

この図では、Math.random() から 1〜6 の整数を作る流れを表しています。

Math.random() は、最初に 0.0以上1.0未満の小数を返します。
それに 6 を掛けることで、0.0以上6.0未満の範囲に広げます。

次に、int へ変換することで小数部分を切り捨て、0〜5 の整数にします。
最後に 1 を足すことで、1〜6 の範囲に調整します。

ここから分かるのは、random() はそのままサイコロの目を返すわけではなく、必要な範囲に合わせて計算して整える必要があるということです。

Mathクラスが役立つ場面

Math クラスは、学習用の計算だけでなく、実際のプログラムでもいろいろな場面で役立ちます。

場面使うメソッドの例
点数の比較max()、min()
温度差や距離差の大きさabs()
面積や長さの計算sqrt()、pow()
ゲームや抽選random()
小数の切り上げ・切り下げceil()、floor()

たとえば、ゲームなら random() がよく使われます。
点数管理なら max() や min() が便利です。
距離や差の大きさを扱うなら abs() が役立ちます。

鬼滅の刃でたとえると、Math クラスは任務ごとに使える計算道具です。

訓練点の比較。
移動距離の計算。
補給物資の切り上げ計算。
任務抽選のランダム処理。

こうした場面で、Math クラスを使うとコードを短く、分かりやすくできます。

よくある注意点

Math クラスを使うときには、いくつか注意点があります。

注意点内容
new は不要Math.max() のようにクラス名で呼び出す
戻り値の型に注意するsqrt() や pow() は double 型を返す
random() はそのままだと小数整数にしたいなら計算と型変換が必要
max() や min() はオーバーロードされている引数の型に応じて適切なメソッドが使われる
ceil() や floor() の結果も double 型4 や 3 ではなく 4.0、3.0 のように返る

特に大切なのは、戻り値の型です。

たとえば、Math.sqrt(25) の結果は 5 ではなく、double 型の 5.0 です。
Math.pow(2, 3) の結果も 8 ではなく、double 型の 8.0 です。

メソッド戻り値の例戻り値の型
Math.max(5, 10)10int
Math.sqrt(25)5.0double
Math.pow(2, 3)8.0double
Math.random()0.0以上1.0未満double

見た目が整数に近くても、実際には double 型として返るメソッドがあります。
この点を意識しておくと、変数に代入するときに迷いにくくなります。

Mathクラスを見るときの大切な感覚

Math クラスを理解するときは、次のように見ると分かりやすいです。

見るポイント確認すること
何を計算するメソッドか最大値、最小値、絶対値、平方根、累乗、乱数など
引数は何か比べる値、計算したい値、累乗の底と指数など
戻り値は何かint なのか、double なのか
クラスメソッドかMath.メソッド名() の形で呼び出す
他のクラスと組み合わせるかInteger.parseInt() で入力を数値にしてから Math を使うなど

鬼滅の刃でたとえると、Math クラスは鬼殺隊本部の計算道具箱です。

大きい値を選ぶなら max()。
小さい値を選ぶなら min()。
差の大きさを見るなら abs()。
平方根を求めるなら sqrt()。
累乗なら pow()。
抽選なら random()。

必要な計算に合わせて、道具箱から正しい道具を選ぶことが大切です。

Math クラスを使えるようになると、数値の比較、絶対値、累乗、平方根、乱数など、少し高度な計算を短く分かりやすく書けるようになります。

Javaには、こうした便利な機能が最初から用意されています。
すべてを自分で作ろうとするのではなく、必要な場面で標準クラスを上手に使うことも、Javaエンジニアとして大切な力です。