web-dev-qa-db-ja.com

JSはランダムなブール値を生成します

簡単な質問ですが、ここのニュアンスに興味があります。

私は自分で思いついた次の方法を使用してランダムなブール値を生成しています:

const Rand = Boolean(Math.round(Math.random()));

random()が表示されるたびに、常に落とし穴があるように見えます-それは本当にランダムではなく、何か他のものによって危険にさらされているなどです。だから、私は知りたい:

a)上記はベストプラクティスの方法ですか?

b)私は物事を考え直していますか?

c)私は物事を考えていますか?

d)私が知らないより良い/速い/エレガントな方法はありますか?

(BとCが相互に排他的である場合もある程度興味があります。)

更新

それが違いを生むなら、私はこれをAIキャラクターの動きに使用しています。

84
Ben

技術的には、コードは問題ないように見えますが、少し複雑すぎます。 Math.random()の範囲は[0、1)であるため、「Math.random()」を「0.5」と直接比較できます。範囲は[0、0.5)と[0.5、1)に分割できます。

var random_boolean = Math.random() >= 0.5;
221
Kelvin

プロジェクトに lodash がある場合、次のことができます。

_.sample([true, false])
20

より暗号的に安全な値を得るには、最新のブラウザで crypto.getRandomValues を使用できます。

サンプル:

var randomBool = (function() {
  var a = new Uint8Array(1);
  return function() {
    crypto.getRandomValues(a);
    return a[0] > 127;
  };
})();

var trues = 0;
var falses = 0;
for (var i = 0; i < 255; i++) {
  if (randomBool()) {
    trues++;
  }
  else {
    falses++;
  }
}
document.body.innerText = 'true: ' + trues + ', false: ' + falses;

cryptoオブジェクトはDOM APIであるため、Nodeでは使用できませんが、 Nodeには同様のAPIがあります です。

11

別の方法:

Boolean(Math.round(Math.random()))
0
Damjan Pavlica

Alexander O'Mara の回答

ノードコードスニペットを追加するだけ

const crypto = require('crypto');
const randomBool = (function () {
    let a = new Uint8Array(1);
    return function () {
        crypto.randomFillSync(a);
        return a[0] > 127;
    };
})();

let trues = 0;
let falses = 0;
for (let i = 0; i < 100; i++) {
    if (randomBool()) {
        trues++;
    }
    else {
        falses++;
    }
}

console.log('true: ' + trues + ', false: ' + falses);
0
bFunc

これはどう?

return Math.round((Math.random() * 1) + 0) === 0;
0
Alex