198 votes

JS génère un booléen aléatoire

Question simple, mais je suis intéressé par les nuances ici.

Je génère des booléens aléatoires en utilisant la méthode suivante que j'ai moi-même mise au point:

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

Chaque fois que random() apparaît, il semble y avoir toujours un piège - ce n'est pas vraiment aléatoire, c'est compromis par quelque chose ou autre, etc. Donc, j'aimerais savoir:

a) Est-ce la meilleure pratique pour le faire?

b) Est-ce que je me prends trop la tête?

c) Est-ce que je ne réfléchis pas assez?

d) Existe-t-il une meilleure / plus rapide / plus élégante façon que je ne connais pas?

(Aussi un peu intéressé de savoir si B et C sont mutuellement exclusifs.)

Mise à jour

Si cela fait une différence, j'utilise ceci pour le déplacement d'un personnage AI.

43 votes

const rand = Math.random() < 0.5 est équivalent et plus simple.

3 votes

Vous ne pouvez atteindre que pseudo-aléatoire, pas de vrai aléatoire.

1 votes

Rien n'est en fait aléatoire, le but est d'atteindre le plus près possible de l'aléatoire.

504voto

Kelvin Points 2052

Vous pouvez comparer Math.random() à 0.5 directement, car la plage de Math.random() est [0, 1) (ce qui signifie 'dans la plage de 0 à 1 incluant 0, mais pas 1'). Vous pouvez diviser la plage en [0, 0.5) et [0.5, 1).

var random_boolean = Math.random() < 0.5;

// Exemple
console.log(Math.random() < 0.1); // probabilité de 10% d'obtenir vrai
console.log(Math.random() < 0.4); // probabilité de 40% d'obtenir vrai
console.log(Math.random() < 0.5); // probabilité de 50% d'obtenir vrai
console.log(Math.random() < 0.8); // probabilité de 80% d'obtenir vrai
console.log(Math.random() < 0.9); // probabilité de 90% d'obtenir vrai

11 votes

J'aime cette solution, car elle vous permet de régler la probabilité de vrai/faux

0 votes

Si vous changez le nombre 0,5 à 0,9 par exemple, est-ce que cela augmente la probabilité de faux, et comment ?

0 votes

Si vous le changez de 0,5 à 0,9. Ensuite, la probabilité est susceptible d'être modifiée. Je pense que vous pouvez essayer avec un grand nombre de boucles aléatoires, comme 10000 itérations.

32voto

Nishant Shreshth Points 5675

Si votre projet utilise lodash, vous pouvez :

_.sample([true, false])

Alternativement, vous pouvez utiliser votre propre fonction d'échantillonnage (source) :

const sample = arr => arr[Math.floor(Math.random() * arr.length)];

16voto

Alexander O'Mara Points 23319

Pour une valeur plus sécurisée du point de vue cryptographique, vous pouvez utiliser crypto.getRandomValues dans les navigateurs modernes.

Exemple :

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;

Notez que l'objet crypto est une API DOM, donc il n'est pas disponible dans Node, mais il existe une API similaire pour Node.

4 votes

Math.random() est notoirement non-aléatoire à bien des égards, grande suggestion alternative

3 votes

Je vais juste ajouter une petite correction ici, car j'ai découvert après 50 000 000 exécutions que cela générait en moyenne 0,78% ou plus de zéros : return a[0] <= 127; (Sinon 127 n'est jamais inclus)

2 votes

@AmundMidtskog Bonne décision. J'aurais dû taper: a[0] > 127

12voto

user12066722 Points 171
!Math.round(Math.random());

­­­­­­­­­­­­­­

translate to

!Math.round(Math.random());

­­­­­­­­­­­­­­

8voto

Arthur Khazbs Points 366

Impressionné par la réponse de Kelvin, j'aimerais suggérer une solution assez similaire mais légèrement améliorée.

var randomBoolean = Math.random() < 0.5;

Cette solution est un peu plus facile à lire, car le nombre à droite de < vous indique la probabilité d'obtenir true plutôt que d'obtenir false, ce qui est plus naturel à comprendre. De plus, < est un symbole plus court que >=;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X