【Java】数学演算のまとめ

#数学演算
##基本演算
* Mathクラス
    * 全機能がクラスメソッド化されている
    * Mathクラスのインスタンス化は不要(できない)

```java
public class Main {
  public static void main(String[] args) {
    //絶対値,最大,最小
    System.out.println(Math.abs(-100)); //100
    System.out.println(Math.max(6, 3)); //6
    System.out.println(Math.min(6, 3)); //3
    //切り上げ
    System.out.println(Math.ceil(1234.56));  //1235.0
    //切り捨て
    System.out.println(Math.floor(1234.56)); //1234.0
    //四捨五入
    System.out.println(Math.round(1234.56)); //1235
    //平方根
    System.out.println(Math.sqrt(10000));    //100.0
    //立方根
    System.out.println(Math.cbrt(10000));    //21.544346900318835
    //xのy乗
    System.out.println(Math.pow(2, 4));      //16.0
    //角度をradianに変換
    System.out.println(Math.sin(Math.toRadians(30))); //0.49999999999999994
    System.out.println(Math.cos(Math.toRadians(60))); //0.5000000000000001
    System.out.println(Math.tan(Math.toRadians(45))); //0.9999999999999999
    //底eの対数、底10の対数
    System.out.println(Math.log(100));                //4.605170185988092
    System.out.println(Math.log10(100));              //2.0
  }
}

```

##long型以上の整数演算
* **BigIntegerクラス**
    * long値を超えた値が正しく出力
    * cf:**BigDecimalクラス**では広範囲浮動小数点数を正しく演算

```java
//NG例 long型上限を超えたところからオーバーフロー
public class Main {
  public static void main(String[] args) {
    long result = 1;
    for (var i = 1; i < 26; i++) {
      result *= i;
      System.out.println(result);
      //1,2,,,(略),2432902008176640000,-4249290049419214848,-1250660718674968576,8128291617894825984,-7835185981329244160,7034535277573963776
    }
  }
}
```

```java
//OK演算
import java.math.BigInteger;
public class Main {
  public static void main(String[] args) {
    var result = BigInteger.valueOf(1);
    for (var i = 1; i < 26; i++) {
      result = result.multiply(BigInteger.valueOf(i));
      System.out.println(result);
      //1,2,6,,,(略),,2432902008176640000,51090942171709440000,1124000727777607680000,25852016738884976640000,620448401733239439360000,15511210043330985984000000
    }
  }
}
```

##乱数生成
* **Randomクラス**

```java
import java.util.Random;

public class Main {
  public static void main(String[] args) {
    var rnd = new Random();
    //ブール値でで乱数生成
    System.out.println(rnd.nextBoolean()); //true
    //Floatで乱数生成(0~1)
    System.out.println(rnd.nextFloat());   //0.11219084
    //Doubleで乱数生成(0~1)
    System.out.println(rnd.nextDouble());  //0.983418224742081
    //Intで乱数生成(0~bound)
    System.out.println(rnd.nextInt(400) + 100); //448
    //Longで乱数生成
    System.out.println(rnd.nextLong()); //2297825179350643621
    var data = new byte[5];
    //ランダムでバイトを生成、引数指定のバイト配列に配置
    rnd.nextBytes(data);
    for (var b : data) {
      System.out.print(b + " "); //63 -54 23 113 -76 
    }
  }
}
```

##数値整形
* **NumberFormatクラス**
    * setCurrency / setGroupingUsed などで標準フォーマットカスタマイズ可能
   
```java
import java.text.NumberFormat;
import java.util.Locale;

public class Main {
  public static void main(String[] args) {
    var num1 = 1234.5678;
    //通貨フォーマット
    var nf1 = NumberFormat.getCurrencyInstance(Locale.JAPAN); 
    //整数フォーマット
    var nf2 = NumberFormat.getIntegerInstance();
    //汎用数値フォーマット（getInstance）
    var nf3 = NumberFormat.getNumberInstance();
    System.out.println(nf1.format(num1)); //￥1,235
    System.out.println(nf2.format(num1)); //1,235
    System.out.println(nf3.format(num1)); //1,234.568

    var num2 = 0.567;
    //%フォーマット
    var nf4 = NumberFormat.getPercentInstance();
    System.out.println(nf4.format(num2)); //57%
  }
}
```

##配列操作
* **Arraysクラス**
    * 配列は後からサイズ変更できない→**copyOfメソッド**でサイズの異なる配列に値を複製
    * copyOf、copyOfRangeは**シャローコピー**
    * 参照型の場合、コピー元が変わるとコピー先も変わってしまう
    * →**ディープコピー**

```javascript
//Shallow copy
import java.util.Arrays;

public class Main {
  public static void main(String[] args) {
    var  array1 = new String[] { "dog", "cat", "mouse", "fox", "lion" };
    //配列をソート
    Arrays.sort(array1);
    //配列を文字列化
    System.out.println(Arrays.toString(array1)); //[cat, dog, fox, lion, mouse]
    //ソート済の配列から値を検索
    System.out.println(Arrays.binarySearch(array1, "mouse")); //4

    var array2 = new String[] { "あ", "い", "う", "え", "お" };   
    //配列コピー、引数に長さ、不足分は0/nullで埋める
    var array3 = Arrays.copyOf(array2, 2);
    System.out.println(Arrays.toString(array3)); //[あ, い]
    
    //配列を引数で範囲指定してコピー
    var array4 = Arrays.copyOfRange(array2, 1, 7);
    System.out.println(Arrays.toString(array4)); //[い, う, え, お, null, null]

    //配列に値を設定
    Arrays.fill(array4, 4, 6, "―");
    System.out.println(Arrays.toString(array4)); //[い, う, え, お, ―, ―]
  }
}
```

```java
//Deep copy
import java.util.Arrays;

public class Main {
  public static void main(String[] args) {
    var list1 = new StringBuilder[] {
        new StringBuilder("ドレミファドーナツ"),
        new StringBuilder("ARAMA"),
        new StringBuilder("ハニホヘト")
      };

    var list2 = new StringBuilder[list1.length];
    for (var i = 0; i < list1.length; i++) {
      list2[i] = new StringBuilder(list1[i].toString());
    }

    list1[2].append("ハロー");
    System.out.println(Arrays.toString(list1)); //[ドレミファドーナツ, ARAMA, ハニホヘトハロー]
    System.out.println(Arrays.toString(list2)); //[ドレミファドーナツ, ARAMA, ハニホヘト]
  }
}
```