質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.02%

  • JavaScript

    13789questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • HTML

    7508questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Math.floor( Math.random() * (max - min + 1) ) + min;でらんすう乱数を取得できるのはなぜ?

受付中

回答 3

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 399

abinai

score 3

なぜmax~minの範囲の乱数を取得できるのかしりたかったので、幾つかのサイトをめぐってみましたが、[Math.floor( Math.random() * (max - min + 1) ) + min;]がなぜmax~minの範囲の乱数を取得できるのかを書いてありませんでしたので教えてもらいたいと思い質問しました。拙い質問ですがよろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+4

  • Math.random() 0 以上 1 未満の範囲内でランダムな浮動小数点を返します
  • Math.floor()引数の数値以下の最大の整数を返します

では、Math.floor()Math.random()の結果を渡してみるとどうなるでしょうか。

Math.floor(Math.random());// 0


Math.floor()は、小数点以下を切り捨て、整数部分を返すので、常に 0 を返します。

このままでは、1つの数値しか得ることができません。より多くの数値を得るためには、Math.floor()に渡される数値を大きくする必要があります。そこで、Math.random()を2倍したときに何が起こるかを見てみましょう。

Math.floor(Math.random() * 2);// 0
Math.floor(Math.random() * 2);// 0
Math.floor(Math.random() * 2);// 0
Math.floor(Math.random() * 2);// 1
Math.floor(Math.random() * 2);// 0


先ほども書きましたが、Math.random()0 ~ 0.99999...の範囲の数値を返します。そして、これを2倍しているので、得られる数値の範囲は0 ~ 1.9999...となります。なので、Math.floor()にこの結果を渡したとき、 0  1 の2つの値が得られるようになりますMath.random()にかける数を3倍, 4倍, 5倍, ...と増やしていくごとに、得られる数値の数も3個, 4個, 5個...と増えていきます。

次に、5 ~ 10の範囲でランダムな整数を生成したい場合を考えてみましょう。5 ~ 10には、5, 6, 7, 8, 9, 10というように6つの数値が存在することがわかります。つまり、Math.random()に6をかける必要があると言うことです。ここで、なぜそんなことをするのかは置いておいて、5(最小値)と10(最大値)から6という数値を作ってみます。よく考えてみると、6という数値は(最大値) - (最小値) + 1という式で作ることができるとわかります。
では、早速今導き出した式を使ってランダムな整数を出力してみましょう。

Math.floor(Math.random() * (10 - 5 + 1));// 1
Math.floor(Math.random() * (10 - 5 + 1));// 3
Math.floor(Math.random() * (10 - 5 + 1));// 5
Math.floor(Math.random() * (10 - 5 + 1));// 0
Math.floor(Math.random() * (10 - 5 + 1));// 3
Math.floor(Math.random() * (10 - 5 + 1));// 5
Math.floor(Math.random() * (10 - 5 + 1));// 2


このままではまだ問題が残っていることに気づいたでしょうか?そうです、5 ~ 10の範囲ではなく、0 ~ 5の範囲のランダムな整数になってしまっています。どうすれば、0 ~ 55 ~ 10にすることができるでしょうか。

0, 1, 2, 3, 4, 5
5, 6, 7, 8, 9, 10


よく見てみると、1行目の数値それぞれに 5 ずつ加えると、2行目の数値になることがわかります。また、この 5 というのは今回作りたい乱数の中で最小の値です。
これらを踏まえた上で、正しく動作するようにコードを修正すると以下のようになります。

Math.floor(Math.random() * (10 - 5 + 1)) + 5;// 9
Math.floor(Math.random() * (10 - 5 + 1)) + 5;// 5
Math.floor(Math.random() * (10 - 5 + 1)) + 5;// 6
Math.floor(Math.random() * (10 - 5 + 1)) + 5;// 8
Math.floor(Math.random() * (10 - 5 + 1)) + 5;// 10
Math.floor(Math.random() * (10 - 5 + 1)) + 5;// 7


これで5 ~ 10の範囲でランダムな整数を生成することができるようになりました。この一連の流れから、Math.random()(最大値) - (最小値) + 1をかけて、それに最小値を足すことで最小値 ~ 最大値の範囲のランダムな整数を生成できるとわかりました。あとは、最小値、最大値に対してmin, maxという変数を用意すれば質問文にあるMath.floor( Math.random() * (max - min + 1) ) + min;が出来上がります。

var min = 5, max = 10;
Math.floor(Math.random() * (max - min + 1)) + min;

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

Math.random()は、0以上1未満の値をとる。
Math.floor()は引数として与えた数以下の最大の整数をとる。

以上が理解できれば、掲出の数式が取りうる範囲は自明かと思いますが。得心できないなら、数直線などを描いて考えてみては?

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/12 08:15

    確かにそうなんですが、。うーん、そうなんですが....

    キャンセル

  • 2017/09/12 10:17

    「そうなんですが…」の後が続かないので、「何が分からないのか」が分かりません。
    分からない内容を具体化してみてはどうでしょうか。
    https://teratail.com/help/question-tips#questionTips2

    キャンセル

  • 2017/09/12 12:49

    こういうときは境界値を考えてみるといいです。
    random()が0の時、式の値は何になりますか?
    random()が1の時、式の値は何になりますか?
    これでも「そうなんですが……」だと、ちょっとどなたにもアドバイスは難しいのでは。

    キャンセル

  • 2017/09/12 12:58

    Math.floor( Math.random() * (max - min + 1) ) + min;
    Math.floor( [0, 1) * (max - min + 1) ) + min;
    Math.floor( [0, max - min + 1) ) + min;
    [0, 1, ..., max - min] + min;
    [0 + min, 1 + min, ..., max - min + min];
    [0 + min, 1 + min, ..., max];
    みたいに数式っぽく変化させるとわかり易いですかね?


    それとも、一様であるかどうかについて気にしてらっしゃる?

    キャンセル

+1

Math.floor( Math.random() * (max - min + 1) ) + min;

数字適当に当てはめてみてはどうですか?
例えばmax = 10 , min = 2 
そうすると単純に
Math.floor( Math.random() * (9) ) + 2;
となり

ランダム値が最低の0でも 最後に2を足してるため最低でもmin以上の値になる。
ランダム値が最高(ではないけど)の0.9でも、9*0.9=8.1 これを切り捨てして 8 で最後に2を足して10でmax以下になる。

max - min + 1 でminを引いてるのは最後に+minをしてるから
ここで引かないと最大値が12になってしまう。
+1はランダム値が1未満だからそのままで掛けて切り捨てちゃうと
最大値にどうしても届かないので足しといて上げる。

自分も今回これを初めて見てよくわからなかったですけど、
何回か当てはめながらやったらわかったので試してみてはいかがでしょうか

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 91.02%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    13789questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • HTML

    7508questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。