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

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

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

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

Q&A

解決済

2回答

1243閲覧

xorShiftで浮動小数点数を得たい

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

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

0グッド

0クリップ

投稿2023/01/10 14:14

前提

ここに質問の内容を詳しく書いてください。
javascriptで、再現性のある浮動小数点数の乱数を生成するにはどうすればいいのでしょうか?xorShiftで試してみたのですが、どうしても数値が偏ったものになってしまいます。

実現したいこと

軽いらしいのでxorShiftの生成法がいいです。Math.random()のように0から1の間の浮動小数点数を得られるものがいいです。

該当のソースコード

javascript

1 function seed(seed){ 2 this._x = 123456789; 3 this._y = 362436069; 4 this._z = 521288629; 5 this._w = seed; 6 } 7 8 seed.prototype.xorShift = function() { 9 let t; 10 t = this._x ^ (this._x << 11); 11 this._x = this._y; this._y = this._z; this._z = this._w; 12 this._w = Math.abs((this._w ^ (this._w >>> 19)) ^ (t ^ (t >>> 8))); 13 return this._w; 14 }; 15 16 17let rand = new seed(1); 18console.log(rand.xorShift()); 19//638953871 20 21rand = new seed(2); 22console.log(rand.xorShift()); 23//638953870 24 25//偏った結果になる 26 27rand = new seed(88675123); 28for(let i = 0; i < 10; i++){ 29 console.log(rand.xorShift()); 30}//繰り返したときは偏らない 31 32/* 33593279510 34458295579 351794091433 36661847884 37516391490 381924314800 391695021998 40717233955 41137846187 42271094485 43*/ 44

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

0から1の間の浮動小数点数を得られるもの

こちらについて。
Math.random()同様[0,1)の均等分布する乱数を作るには、
・浮動小数点数の1を用意する
・ビット列で見て、符号と指数をそのままに仮数部をランダム値で置き換える
・浮動小数点数と見て1を引く
でできると思います。
JavaScriptで浮動小数点数とビット列を読み替えるには、ArrayBufferを用意しFloatとUintのTypedArrayとして見て処理するのがよいです。
参考: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/TypedArray

投稿2023/01/11 13:34

ikadzuchi

総合スコア3047

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2023/01/11 18:46

回答ありがとうございました!
guest

0

繰り返したときは偏らない

擬似乱数列は、そういう使い方をするものです。

「シード値を変えて1個だけ生成することを繰り返す」ようなものではありませんので、「seed(1)での1個目の乱数とseed(2)での1個目の乱数が近い値である」ことを気にする必要がありません。

なお、実用的には「最初数個を捨ててスタートする」ことで、初っ端の乱数がシード値からすぐわかるような事態を避けるように実装してある例も多いです。

投稿2023/01/10 14:26

編集2023/01/10 14:32
maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2023/01/10 14:56

回答ありがとうございます。seed値を変えるだけで結果も劇的に変わるようなプログラムはどう書けばいいでしょうか?浮動小数点数で得られるような方法が良いです。
maisumakun

2023/01/10 14:59

回答中にあるように、最初数個を捨ててスタートする(コンストラクタで初期化を行った後に、いくつか乱数を生成するだけ生成して進めておく)ようにしてはどうでしょうか。
退会済みユーザー

退会済みユーザー

2023/01/10 15:07

seed関数の情報を保存しておく必要があるということでしょうか?
maisumakun

2023/01/10 16:12

それはすでに行っていませんか?
退会済みユーザー

退会済みユーザー

2023/01/10 17:55

プログラムを実行したあと、処理は一度中断されるとして、乱数を回した後の状態でseed関数を保存しておかないと、繰り返した回数がリセットされてしまうという事です
退会済みユーザー

退会済みユーザー

2023/01/10 18:25

追記:javascriptの内部プログラムでのMath.random()はどういうプログラムコードになっているのでしょうか?これがわかれば大丈夫です
退会済みユーザー

退会済みユーザー

2023/01/11 18:46

返答ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問