いろんな言語で乱数取得

以前、[現在時刻の取得方法](https://qiita.com/gitcho/items/d0b375586a9b447d28c1)についてまとめたが、乱数を取得することも多いと感じたので、擬似乱数として0以上10未満の整数を取得する方法まとめることにした。なお、乱数生成のアルゴリズムについては奥が深いため、ここで紹介する方法は品質にはこだわらず、あくまで「手軽に乱数を作るならこうする」というお決まり的な自分用メモなのであしからず。

# C言語
はじめはC言語。というのも、C言語で乱数を取得する方法を理解すれば、だいたいどの言語でも「この手順が必要になる」という大枠をつかむことができるから。

- [参考サイト](https://linuxjm.osdn.jp/html/LDP_man-pages/man3/rand.3.html)

`rand()`関数を利用すると0以上`RAND_MAX`以下の整数を取得できる。ただし意図的に`srand()`関数で乱数のシードを設定しなければ、シードとして`1`が仮定されるため、実行の都度同じ乱数が生成されてしまう。これを避けるためによく使われる手段が、現在時刻をシードとして設定すること。

1. 現在時刻（経過秒数）を取得する
2. `srand()`関数で現在時刻をシードに設定する
3. `rand()`関数で乱数を取得する
4. 取得した乱数を剰余などで算術演算して必要とする範囲に収める

```c
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

/**
 * min以上max未満の整数をランダムに取得する
 */
int getRandomInt(int min, int max){
	return rand() % (max - min) + min;
}

int main(void){
	srand((unsigned)time(NULL));//経過秒数でシードを設定する
	printf("%d\n", getRandomInt(0, 10));
	return 0;
}
```

# Java
- https://docs.oracle.com/javase/jp/8/docs/api/java/util/Random.html

Javaは`java.util.Random`クラスがあるため、これを使うのが簡単。

1. `java.util.Random`クラスのインスタンスを生成する
2. `nextInt()`メソッドで乱数を取得する

```java
import java.util.Random;
public class Sample{
  public static void main(String[] args){
    Random r = new Random();//引数にシードを設定することも可。省略するとSystem.nanoTimeに応じて決定される値が仮定される
    System.out.println(r.nextInt(10));//0以上10未満の整数を取得
  }
}
```

なお、`java.lang.Math`クラスに`random()`メソッドがあるため、これを使う方法もあるが、実装例はJavaScriptと似ているため割愛。

- https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Math.html

# C# 
Javaとほぼ同じ。`System.Random`クラスを利用するのが簡単。

```cs
using System;
namespace Sample{
    class Program{
        static void Main(string[] args){
            Random r = new Random();//引数にシードを設定することも可。省略するとEnvironment.TickCountに応じて決定される値が仮定される
            Console.WriteLine(r.Next(10));//0以上10未満の整数を取得
        }
    }
}
```

# JavaScript(TypeScript)
- [参考サイト](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/random)

JavaScriptの場合は`Math.random()`を利用する。ただし、この関数は

- 0.0以上1.0未満の小数を返却する
- シードを設定できない

```ts
/**
 * min以上max未満の整数をランダムに取得する
 */
function getRandomInt(min: number, max: number): number {
    min = Math.ceil(min);   //その数以上の最小の整数にする。1.23 → 2
    max = Math.floor(max);  //その数以下の最大の整数にする。1.23 → 1
    return Math.floor(Math.random() * (max - min)) + min;
}
```

# golang
- [参考サイト](https://golang.org/pkg/math/rand/)

Goでは`Math/rand`パッケージのを利用する。シードは`rand.Seed()`で設定するが、デフォルトは`1`が仮定されているため、C言語同様、意図的に現在時刻などで設定するのが一般的。C言語と違い、`Intn()`を使えば、剰余を取る必要はない。

```go
package main
import (
	"fmt"
	"math/rand"
	"time"
)
func main(){
	rand.Seed(time.Now().UnixNano()) //経過秒数をシードに設定
	fmt.Println(rand.Intn(10)) // 0以上10未満の整数を取得
}
```

# Ruby
- [参考サイト](https://docs.python.org/ja/3/library/random.html)

`Random`クラスを利用するのが簡単。`rand()`に指定する値が`Int`か`Float`か`1..10`などの範囲指定かで動きが変わるので注意。
C言語みたいに`srand()`でシードを設定することもできる。

```ruby
r = Random.new()  # 引数にシードを設定する。省略するとRandom.new_seedが仮定される
puts r.rand(10)   # 0以上10未満の整数を取得
puts r.rand(10.0) # 0.0以上10.0未満の小数を取得
```

# Python
- [参考サイト](https://docs.python.org/ja/3/library/random.html)

`random`モジュールを使うのが簡単だが、`random.randrange()`は**未満**、`random.randint()`は**以下**と地味に使い間違えやすい関数が並んでいるので注意すること。
シードを設定する場合は、意図的に`random.seed`を設定する。設定しない場合はシステム時刻が仮定される。詳細は参考サイト参照。

```python
import random
print(random.randrange(0, 10))  # 0以上10未満の整数を取得
print(random.randint(0, 10))  # 0以上10 以 下 の整数を取得
```

# kotlin
- [参考サイト](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.random/-random/index.html)

Javaと同じく、`Random`クラスを使う。シードを設定したいときは[こっち](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.random/-random.html)を使う。

```kotlin
import kotlin.random.Random
fun main(args: Array<String>) {
	println(Random.nextInt(10))  //0以上10未満の整数を取得
}
```

# swift
- [参考サイト](https://github.com/apple/swift-evolution/blob/master/proposals/0202-random-unification.md)

swift4.2からRandom APIが登場したのでこれを使うのが簡単。

```swift
print(Int.random(in: 0..<10)) //0以上10未満の整数を取得
```

# シェルスクリプト
bashやzshを使っているならシェル変数`$RANDOM`に乱数が格納されている。Windowsのbatにも同様に`%RANDOM%`がある。

```
echo $RANDOM
```

# SQL
乱数を生成できるSQL関数が用意されているデータベースの場合は、SQLで乱数を取得することもできる。

## MySQL
- [参考サイト](https://dev.mysql.com/doc/refman/5.6/ja/mathematical-functions.html)

`RAND()`を使うと0.0以上1.0未満の小数が得られるのでこれを算術演算して必要な範囲に収めればいい。

```sql
SELECT FLOOR((RAND() * 10))
```

## PostgreSQL
- [参考サイト](https://www.postgresql.jp/document/11/html/functions-math.html)

`RANDOM()`を使う。MySQLと関数名が違うが同じことなので割愛。


# 結言
とりあえず、自分が関わったことのある言語について乱数取得方法をまとめてみた。
今後、別の言語でも乱数が必要になることがあれば随時更新する予定。