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)
返回雙曲正切值

,和方法採用以弧度表示的角度。要將角度從度數轉換為弧度,反之亦然,該類提供了兩種特殊方法:Math.sin()Math.cos()Math.tan()Math

方法 描述
double toRadians(double angdeg)
將角度從度數轉換為弧度
double toDegrees(double angrad)
將角度從弧度轉換為度

順便說一句,除了方法,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)
的自然對數aln(a)
double log10(double a)
以 10 為底的對數alog10(a)
double log1p(double x)
的自然對數x + 1ln(x + 1)
double expm1(double x)
ex-1

如果您想要數字的平方根或立方根,則sqrt(a)cbrt(a)方法將為您服務。

平方根可以計算如下:

Math.sqrt(2)

如果想求更高次方的根,那就用取冪的方法:a的次方¼就是四次方根,等等。

Math.pow(2, 0.25)

對於對數和指數,有log(a)(自然對數)和exp(x)(指數)方法。要計算以 10 為底的對數,我們有log10(a)

如果您希望數字的對數b以 base 為底a,請使用這個簡單的公式:loga(b) = ln(b) / ln(a)

有用的方法

如果您執行的計算涉及非常小的 值x,那麼最後兩個函數 —log1p()expm1()— 可能對您有用。

添加非常小和非常大的double變量時,您經常會發現非常小的值被簡單地忽略(丟棄)為無關緊要。事實上,如果您使用log()exp()方法,就會發生這種情況。為了解決這個問題,程序員想出了只返回“小的重要部分”的函數

例子:

假設您要計算 的自然對數1 + x,其中x是。您不能簡單地將此數字傳遞給該方法,因為如果您添加和,您將得到。是一個很小的數,加起來就會被完全捨棄。10-20log()110-20110-20

因為數學經常涉及計算log()接近 的數字1,程序員想出了一個方法來解決這個問題:不是將數字本身傳遞給方法,而是只傳遞它與 的差值1



3.最小值和最大值

兩個更有用的函數是min(a, b)max(a, b)。正如您可能已經猜到的那樣,第一個返回兩個數字中的最小值:

Math.min(a, b)

第二個返回兩個數字中的最大值:

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;
使用三元運算符 缺點:
- 龐大的代碼
- 計算執行兩次
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()andmax()方法的好方法。

計算多個數字或變量的最小值(或最大值)。嵌套調用這些方法非常方便。

以下是查找 3 個數字中最小值的方法:

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

所以呢?超級方便:計算兩個數的最小值,然後返回這個數和第三個數的最小值。

同理求出四個數中的最小值:

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

也就是說,我們可以把這個公式寫得更清楚一點:

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

該方法的工作原理相同max()

使用if-else運算符或三元運算符會使這些代碼片段更加繁瑣。但是使用min()max()方法是完美的。