やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

組込ライブラリ(Random)

 乱数。

成果物

情報源

Random

MT19937に基づく擬似乱数生成器を提供するクラスです。

オリジナル版 http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/mt.html

メンバ抜粋

特異メソッド

bytes new new_seed rand srand urandom

インスタンスメソッド

== bytes rand seed

private特異メソッド

left state

privateメソッド

left marshal_dump marshal_load state

定数

DEFAULT

特異メソッド

メソッド 概要
bytes ランダムなバイナリ文字列を返す
rand 乱数を生成する
srand デフォルトの擬似乱数生成器の種を設定し、古い種を返す
urandom プラットフォームの提供する機能を使って、文字列を返す。
new_seed 乱数の種を生成する
new Randomオブジェクトを生成する

rand

 乱数を生成する。

rand -> Float
rand(max) -> Integer | Float
rand(range) -> Integer | Float | nil
p Random.rand      # 0.0〜1.0
p Random.rand 2    # 0〜1
p Random.rand 6    # 0〜5
p Random.rand 3..7 # 3〜7

 引数が整数のときは0以下だとエラーになる。

p Random.rand 0 # invalid argument - 0 (ArgumentError)
p Random.rand -1 # invalid argument - -1 (ArgumentError)

 引数が浮動少数のときも負数はダメっぽい。

p Random.rand -1.0 # invalid argument - -1.0 (ArgumentError)

 ただ、なぜか0.0を受け付ける。ドキュメントを信じるなら引数は最大値(max)のはずで、最大値が0.0なら他の数は負数になるはず。なのに実際には0.01.0の範囲に見える。少なくとも負数は出てこない。おそらくドキュメントが間違っている?

 たぶん引数なしのrandと同じ結果なのだと思われる。それはrand 1.0と同じ結果だと思われる。つまりrand, rand 0.0, rand 1.0は同じ?

p Random.rand      # 0.0〜1.0?
p Random.rand 0.0  # 0.0〜1.0?
p Random.rand 1.0  # 0.0〜1.0?

 もしや少数のときは範囲が0.01.0に固定? と思ったが違った。出力値をみるかぎり最小値は0.0だと思われる。

p Random.rand 9.0 # 0.0〜9.0
p Random.rand 0.1 # 0.0〜0.1

 引数が0.0のときだけは特殊ということかな? まあ0.0固定にされたり負数が出るようになって困るし。そもそも浮動少数がほしいときは普通デフォルトの0.01.0を求めるだろうからそれでいいんだけど。

bytes

 ランダムなバイナリ文字列を返す。

bytes(size) -> String
Random.bytes(10) # => "\xAC\n\x7F\x8C/\xAA\xC4\x97u\xA6"

 たぶん使わない。

new

new(seed = Random.new_seed) -> Random
r = Random.new
p r        # #<Random:0x002784c0>
p r.class  # Random

 new_seedは新しい種を生成する。でもnewの時点で自動的に生成されるので使う場面はほとんどないのでは?

 種に整数値を渡せる。ランダムにしたいのなら、ある特定の種を渡すメリットはないはず。それでも使ってみる。以下のように種を1234のように固定すると、実行しても毎回おなじところで同じ値が出る。よってランダムとは言えない。わざとそうしたいときは種を固定にすればいいと思うが、レアケースだと思う。

p Random.new(1234).rand

new_seed

 適切な種を返す。

p Random.new_seed

 何度か実行してみたが、実行するたびに異なる数値が返ってくる。ちゃんとランダムになるので問題ないと思う。

 もしC言語だったら実行時間からの経過時間が種になってしまい毎回同じ数列の値を返してしまいランダムにならない。そのため現在時刻を種にすることでランダムにするという手順が必要だった。Rubyではそのような事態は起こらなそうなので問題ないと思う。というか、おそらくRuby内部でそうした手順を自動的にしてくれているのだと思う。

インスタンスメソッド

seed

 種を返す。

r = Random.new
p r.seed

所感

 わざわざRandomクラスを使わずともKernel.#randで簡単に使えるみたい。

p rand      # 0.0..1.0
p rand 2    # 0..2
p rand 1..6 # 1..6

 これで十分だよ。先に言ってくれ。

対象環境

$ uname -a
Linux raspberrypi 5.10.52-v7l+ #1441 SMP Tue Aug 3 18:11:56 BST 2021 armv7l GNU/Linux