1. Java の三角関数

以前に数値の丸めについて学習したときに、このクラスとそのメソッドのいくつかについて理解しましたMath。このクラスをさらに詳しく見ていきます。

名前が示すように、このMathクラスにはプログラマが最も頻繁に使用する数学演算のメソッドが含まれています。最も興味深いものは次のとおりです。

方法 説明
double sin(double d)
角度のサインをdラジアン単位で返します。
double cos(double d)
角度の余弦をdラジアン単位で返します。
double tan(double d)
角度のタンジェントをdラジアン単位で返します。
double asin(double d)
逆正弦を返します
double acos(double d)
逆余弦を返します
double atan(double d)
逆正接を返します
double sinh(double d)
双曲線正弦を返します
double cosh(double d)
双曲線余弦を返します
double tanh(double d)
双曲線正接を返します

、およびメソッドは、ラジアンで表される角度を受け取ります。角度を度からラジアンに、またはその逆に変換するために、このクラスは 2 つの特別なメソッドを提供します。Math.sin()Math.cos()Math.tan()Math

方法 説明
double toRadians(double angdeg)
角度を度からラジアンに変換します
double toDegrees(double angrad)
角度をラジアンから度に変換します

ちなみに、メソッドに加えて、クラスには 2 つの定数変数(クラスの静的フィールド)Mathもあります。

絶え間ない 説明
double Math.PI
「Pi」定数は以下に等しい3.141592653589793
double Math.E
「E」定数は以下に等しい2.718281828459045

これらの関数はすべて、独自のゲームを作成したり、グラフィックスを操作したり、単にマップ上のパスの長さを計算したりする場合に非常に役立ちます。

たとえば、 を計算したい場合はsin(45°)、次のようにします。

Math.sin( Math.toRadians(45) )

以下に例を示します。

public class Main
{
   public static int N = 10;

   public static void drawValue(double y)
   {
     int value = (int) (y * N) + N;
     for (int i = 0; i < 2 * N; i++)
     {
       char c = i == N ? '|': '.';
       if (i == value)
         c = '*';
       System.out.print(c);
     }
     System.out.println();
   }

   public static void main(String[] args)
   {
     for (int i = 0; i < 10 * N; i++)
     {
       double x = i * 1.0 / N;
       double y = Math.sin(x);
       drawValue(y);
     }
   }
}


2. Java の代数関数

ほとんどの場合、プログラマは高校の数学で十分です。サインやコサインさえもコード内に含まれることはほとんどありません。ほとんどの場合、これらはゲーム、マップ、またはゲーム エンジンを操作するときに必要になります。プログラマーの 90% はこのような状況に遭遇したことはありません。

しかし、プログラマーは幾何学以外にも代数関数を使用しなければならない場合があります。そしてもちろん、このMathクラスには最も一般的なものが含まれています。

方法 説明
double sqrt(double a)
の平方根a
double cbrt(double a)
の立方根a
double pow(double a, double b)
べき乗:ab
double exp(double a)
指数関数 (オイラー数の累乗):ea
double log(double a)
の自然対数a:ln(a)
double log10(double a)
の 10 を底とする対数a:log10(a)
double log1p(double x)
の自然対数x + 1:ln(x + 1)
double expm1(double x)
ex-1

数値の平方根または立方根が必要な場合は、sqrt(a)およびcbrt(a)メソッドが役に立ちます。

平方根は次のように計算できます。

Math.sqrt(2)

より高いべき乗根を取得したい場合は、べき乗法を使用します。aつまり¼、4 乗根などです。

Math.pow(2, 0.25)

log(a)対数と指数には、 (自然対数) とexp(x)(指数) の方法があります。10 を底とする対数を計算するには、次のようになりますlog10(a)

数値の対数bを底とする場合はa、次の簡単な式を使用します。loga(b) = ln(b) / ln(a)

便利な方法

の非常に小さな値を含む計算を実行する場合はx、最後の 2 つの関数 (log1p()およびexpm1()) が役立つ可能性があります。

非常に小さいdouble変数と非常に大きい変数を追加する場合、非常に小さい値が重要ではないものとして単純に無視 (破棄) されることがよくあります。実際、log()およびexp()メソッドを使用すると、これが発生します。これを解決するために、プログラマは「重要な小さな部分」のみを返す関数を考案しました。

例:

の自然対数を計算するとします1 + x。ここで、 はxです。と を追加すると が得られるため、この数値を単純にメソッドに渡すことはできません。は非常に小さい数値であるため、数値を加算するときに完全に破棄されます。10-20log()110-20110-20

log()数学では に近い数値のを計算することがよくあるため1、プログラマはこの問題を回避する方法を考え出しました。数値そのものをメソッドに渡す代わりに、数値との差だけを渡すというものです1



3. 最小値と最大値

さらに 2 つの便利な関数は とmin(a, b)ですmax(a, b)。おそらくすでにご想像のとおり、最初の関数は 2 つの数値の最小値を返します。

Math.min(a, b)

2 番目の関数は、2 つの数値の最大値を返します。

Math.max(a, b)

if三項演算子はいつでも記述でき、さらには使用できるのに、なぜこれらの関数が必要なのでしょうか(a < b ? a: b)?

重要なのはコードの読みやすさです。コードがifステートメントで過負荷になり、よりコンパクトな表記法を使用したい場合があります。比較してみましょう:

コード 説明
int x = 0;
if (x-5+y*20 < x*x+y*y)
   x = x-5+y*20;
else
   x = x*x+y*y;
ステートメントを使用するif-else(ステートメントを記述する最も長い方法)
int x = x-5+y*20 < x*x+y*y ? x-5+y*20 : x*x+y*y;
三項演算子の使用の短所:
- コードがかさばる
- 計算が 2 回実行される
int a = x-5+y*20;
int b = x*x+y*y;
int x = a < b ? a : b;
これは素晴らしい書き方ですが、少し冗長です
int x = Math.min(x-5+y*20, x*x+y*y);
まさにその通りです🙂

4. いくつかの数値の最小値と最大値

min()およびメソッドを使用する別の優れた方法がありますmax()

複数の数値または変数の最小値 (または最大値) を計算すること。これらのメソッドをネストした呼び出しを行うと非常に便利です。

最小 3 つの数値を見つける方法は次のとおりです。

Math.min(a, Math.min(b, c))

だから何?これは非常に便利です。2 つの数値の最小値を計算し、この数値と 3 番目の数値の最小値を返します。

4 つの数値の最小値も同じ方法で取得されます。

Math.min(a, Math.min(b, Math.min(с, d)))

そうは言っても、この式をもう少し明確に書くことができます。

Math.min(Math.min(a, b), Math.min(c, d))

このメソッドではすべて同じように機能しますmax()

if-else演算子または三項演算子を使用すると、これらのコード スニペットが少し複雑になります。min()ただし、およびメソッドを使用するのmax()は完璧です。