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()方法是完美的。