Menu

JavaのMathクラス:pow、sqrt、abs、round、random などの使い方

JavaのMathクラスの使い方。Math.pow、Math.sqrt、Math.abs、Math.max と Math.min、round・floor・ceil による丸め、Math.random で範囲内の乱数を作る方法、定数 PI と E を、それぞれの戻り値の型とあわせて解説します。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

static メソッドの道具箱

java.lang.Math は、すぐに使える数学関数を集めたクラスです。べき乗、平方根、絶対値、丸め、三角関数、対数、乱数などがそろっています。使いやすい理由は2つあります。

  • すべての Java ファイルが自動的にインポートする java.lang にあるので、import の行を書く必要がありません。
  • メソッドはすべて static です。Math.sqrt(25) のようにクラス名に対して呼び出し、Math オブジェクトを作ることはありません。static の意味は static メンバーのページ で説明しています。

結果に .0 が付くものと付かないものがあることに注目してください。Math の各メソッドの戻り値の型は決まっていて、それを知ることがこのクラスで学ぶべきことの大半です。

メソッド処理戻り値
Math.pow(a, b)a の b 乗double
Math.sqrt(x)平方根double
Math.cbrt(x)立方根double
Math.abs(x)絶対値x と同じ型
Math.max(a, b) / Math.min(a, b)2つのうち大きいほう / 小さいほう2つの型のうち範囲の広いほう
Math.round(x)最も近い整数double なら longfloat なら int
Math.floor(x) / Math.ceil(x)切り捨て / 切り上げdouble
Math.random()0.0 以上 1.0 未満の乱数double
Math.PI, Math.E定数 π と edouble

Math.pow:べき乗

Math.pow(base, exponent) は数値をべき乗します。2つの double 引数を受け取り、整数を渡した場合でも double を返します。

結果を int に格納するには (int) でキャストします。小さな整数のべき乗なら double の結果は正確なので、キャストしても正しい答えになります。キャストで問題が起きるのは大きな結果のときです。Integer.MAX_VALUE(2,147,483,647)を超える double をキャストすると、ちょうど Integer.MAX_VALUE になるので、(int) Math.pow(2, 40)2147483647 になります。大きなべき乗は long にキャストし、2⁵³ を超えると double ではすべての整数を正確に表せないことも覚えておきましょう。キャストが値に何をするかは 型キャストのページ で解説しています。

Java にはべき乗演算子がありません。2 ^ 3 はコンパイルできますが、^ はビット単位の XOR で、結果は 8 ではなく 1 です。Java の数値計算のコードで、初心者が最もよく犯すバグの1つです。

1000万以上の double は指数表記で表示されるので、10のべき乗を初めて表示したときに驚く人がいます。

1.0E7 は 1.0 × 10⁷ という意味です。値は同じで、表示の形が変わるだけです。ふつうの数字として表示するには、long にキャストするか、String.format("%.0f", value) で書式を指定します。

Math.sqrt と Math.cbrt:平方根と立方根

Math.sqrt(x)x の平方根を double で返します。Math.cbrt(x) は立方根を返します。

負の数の平方根は実数ではないので、Math.sqrt(-4) は例外を投げずに NaN(「非数」)を返します。NaN はそれが関わる計算すべてに広がるので、負の値がありうる場合は、平方根をとる前に入力を確認しましょう。Math.hypot(a, b)sqrt(a*a + b*b) を直接計算するもので、2点間の距離を求めるときによく使われます。

Math.abs:絶対値

Math.abs(x) は符号を取り除きます。powsqrt と違い、渡したのと同じ型を返します。int なら intdouble なら double です。

よくある使い方は、向きではなく大きさだけが重要な差、たとえば2つの位置の間の距離を求めることです。

Math.max と Math.min

Math.max(a, b) は2つの値のうち大きいほうを、Math.min(a, b) は小さいほうを返します。受け取る引数はちょうど2つです。3つ以上なら、呼び出しを入れ子にします。

2つの引数の型が違う場合、範囲の狭いほうが先に拡大変換されます。Math.max(3, 7.5) は2つの double 値を比較し、double を返します。最後の例は値を 0 から 100 の範囲に収めています。Math.min で上限を 100 にし、Math.max で 0 を下回らないようにしています。

丸め:round、floor、ceil

Java には丸めのメソッドが3つあり、丸める方向も戻り値の型も異なります。

  • Math.round は最も近い整数に丸めます。ちょうど半分の値は正の無限大の方向に切り上げられるので、2.53-2.5-2 になります。引数が double なら long を返します(float なら int)。
  • Math.floor は常に負の無限大の方向に切り捨て、double を返します。
  • Math.ceil は常に正の無限大の方向に切り上げ、double を返します。
  • (int) によるキャストは丸めではありません。小数部分を捨てるだけなので、正の数は小さいほうへ、負の数は大きいほうへ動きます。

Math.round(double)long を返すので、キャストなしで int に代入するとコンパイルできません。

int n = Math.round(2.6);          // error: incompatible types: possible lossy conversion from long to int
int m = (int) Math.round(2.6);    // OK、m は 3
long k = Math.round(2.6);         // OK

小数点以下の桁数を指定して丸めるには、桁を上げてから丸め、元に戻します。100 ではなく 100.0double)で割ると、小数部分が残ります。

2行目は longint で割っているので整数除算になり、小数部分が失われます。丸めた数値を表示するだけなら、String.format("%.2f", value) のほうが簡単で、格納されている値も変わりません。

Math.random:乱数

Math.random()0.0 以上 1.0 未満の double を返します。呼び出すたびに値が変わるので、このセクションのプログラムは Run を押すたびに出力が変わります。

範囲内の整数を得るには、この値を引き伸ばし、キャストし、ずらします。min から max まで(両端を含む)の整数なら次のとおりです。

int value = (int) (Math.random() * (max - min + 1)) + min;

min が 1、max が 6 のサイコロで、この式がどう働くかを見てみましょう。

  1. Math.random() * 60.0 以上 6.0 未満の double になります。
  2. (int) で小数部分を捨てると、0, 1, 2, 3, 4, 5 のいずれかになります。
  3. + 1 でそれを 1, 2, 3, 4, 5, 6 にずらします。

1行目には5回分のランダムな出目が表示されます。2行目は1万回の出目を確認するもので、実際には常に lowest: 1, highest: 6 と表示されます。この式は範囲の両端に届き、それを超えることはありません。

Math.random() * (max - min + 1) を囲むカッコには意味があります。キャストは直後の値に適用されるので、(int) Math.random() * 6 は先に Math.random() をキャストします。その結果は常に 0 で、0 * 60 なので、「出目」はすべて同じになってしまいます。

Math.random() はゲームや練習問題には十分です。それ以上の用途では、java.util.Random クラスや ThreadLocalRandom.current().nextInt(min, max + 1)java.util.concurrent にあります)が整数を直接返してくれますし、Random にはシードを渡してテストで同じ数列を再現することもできます。ただし、どれもパスワードやセキュリティトークンには適していません。その用途には java.security.SecureRandom を使いましょう。

Math.PI と Math.E

Math.PI(π)と Math.E(ネイピア数 e)は static final double の定数です。

3.14 と打つ代わりにこれらを使いましょう。double で表せる限りの精度があり、名前を見ればその数が何なのか読む人にわかります。

整数の結果と double の結果

Math のメソッドの多くは double を受け取り、double を返します。int の値を渡すと Java は引数を自動的に double に拡大変換しますが、呼び出しの前に書いた計算は int のまま行われます。間違った答えのほとんどはここから生まれます。

items / perBox7 / 2 で、2つの int 値の割り算は余りを捨てるので、Math.ceil に渡る前に 3 になっています。Math.ceil(3.0)3.0 です。割り算で小数部分が残るように、キャストや 4.0 のようなリテラルで一方のオペランドを double にしましょう。整数除算については 演算子のページ で詳しく説明しています。

一般的なルールはこうです。最終的に欲しい型を決め、小数が重要なら割り算や掛け算を double で行い、intlong へのキャストは最後に1回だけ行います。

そのほかの便利なメソッド

同じクラスにあるメソッドをさらにいくつか紹介します。どれも同じように呼び出します。

  • Math.log は自然対数、Math.log10 は常用対数(底が10)です。
  • Math.floorMod(a, b)b と同じ符号の余りを返します。曜日のように範囲の中で循環させたいときに必要なのはこちらです。% 演算子は a の符号を保ちます。
  • 三角関数のメソッド(sincostan)はラジアンを受け取ります。度数は先に Math.toRadians で変換しましょう。
  • Math.addExactMath.multiplyExact などは、オーバーフローしたときに黙って負の数に回り込むのではなく、ArithmeticException を投げます。

よくある質問

Javaで Math.pow はどう使いますか?

Math.pow(base, exponent)baseexponent 乗を double で返すので、Math.pow(2, 3)8.0 です。結果を int に格納するにはキャストします:int n = (int) Math.pow(2, 10);1024 になります。Java にはべき乗演算子 ^ はありません。^ はビット単位の XOR です。

Math.random で範囲内の乱数を作るには?

Math.random()0.0 以上 1.0 未満の double を返します。min から max まで(両端を含む)の整数が欲しいときは、(int) (Math.random() * (max - min + 1)) + min を使います。サイコロなら (int) (Math.random() * 6) + 1 です。

JavaでMathクラスをインポートする必要はありますか?

ありません。Math はすべての Java ファイルが自動的にインポートする java.lang パッケージにあります。メソッドはすべて static なので、オブジェクトを作らずに Math.sqrt(16) のようにクラス名に対して呼び出します。

Javaの Math.round が long を返すのはなぜですか?

doubleint よりはるかに大きな値を保持できるので、Math.round(double)long を返します。結果を int に代入するにはキャストが必要です:int n = (int) Math.round(2.6);Math.round(float)int を返します。

Math.floor、Math.ceil、Math.round の違いは?

Math.floor は切り捨て(2.72.0-2.3-3.0)、Math.ceil は切り上げ(2.13.0)、Math.round は最も近い整数への丸めで、ちょうど半分のときは大きいほうになります(2.53)。floorceildouble を返し、roundlong を返します。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める