3

La question est simple. J'ai besoin d'une commande de ligne comme,Nombre aléatoire Absolute 1 or -1

Math.round((-Math.random() * 2)) 

, qui sortie juste montre et -1. J'essaie de comprendre mais cela ne semble pas une tâche facile! Je peux utiliser la commande IF comme,

demo = (Math.random()>.5)?(1):(-1); 

mais j'ai besoin de quelque chose de plus rapide, comme une formule mathématique.

Répondre

4

Je ne peux pas imaginer quelque chose de plus rapide que cela:

var n:int = ((Math.random()*4)&2)-1; 

Aucun conditionals, ne compare, aucune fonction autre que aléatoire() :-)

Et voici un juste pour vous faire penser à une autre comment cela fonctionne:

var n:int = (((Math.random()*0xFFFFFFFF) & 0x80000000)>>30) | 1; 
+0

.. wow! ... c'est bon ! .. Merci.. :) ,, –

4
Math.round(Math.random())*2-1; 

Mais pour être honnête, c'est plus lent que la méthode conditionnelle.

var referenceTime:int = getTimer(); 
var randomInt:int; 
for (var i:int=0; i < 1000000; i++) 
{ 
    randomInt = (Math.random()>.5)?1:-1; 
} 

trace(getTimer()-referenceTime); //122ms 
referenceTime = getTimer(); 

for (i=0; i < 1000000; i++) 
{ 
    randomInt = Math.round(Math.random())*2-1; 
} 

trace(getTimer()-referenceTime); //238ms 
+0

vous le savez, la fonction getTimer() vous évitera beaucoup de taper: D – divillysausages

+0

Hey! Je ne savais pas celui-ci! Ça devait être caché: p De toute façon, tu te moque cruellement de moi! – Kodiak

3

Votre deuxième ligne (l'opérateur ternaire) est le moyen le plus rapide de le faire. Si vous appelez cela beaucoup, alors vous pouvez mettre en cache la fonction Math.random() comme:

private var m_ran:Function = Math.random; 

Ou pour le plus rapide accès absolu, vous pouvez pregenerate un tableau de 100 (ou 1000, peu importe) résultats , puis parcourez la liste quand vous en avez besoin. Quelque chose comme:

private var m_nums:Vector.<int> = null; 
private var m_total:int   = 100; 
private var m_curr:int   = 0; 

private function _init():void 
{ 
    this.m_nums   = new Vector.<int>(this.m_total, true); 
    var ran:Function = Math.random; 
    for(var i:int = 0; i < total; i++) 
     this.m_nums[i] = (ran() > 0.5) ? 1 : -1; 
} 

public function getRandom():int 
{ 
    this.m_curr++; 
    if(this.m_curr >= this.m_total) 
     this.m_curr = 0; 
    return this.m_nums[this.m_curr]; 
} 
1
Math.round(Math.random())*(maxValue-minValue+1))+minValue; 

Selon jonsca pourrait être un problème pour définir -1 comme entier ...

6

Si vous voulez une manière plus rapide, vous pouvez le faire comme ceci:

var n:Number=(int(Math.random()>=0.5)<<1)-1.0 

Comment ça marche: Math.random()>=0.5 retournera true ou false

int(true) = 1 
int(false) = 0 

<<1 va multiplier la valeur par 2 si vous avez un int qui est 2 ou 0

maintenant substract 1.0 et vous avez un number qui est 1.0 ou - 1.0

Voici quelques tests en temps réel avec leur vitesse: http://wonderfl.net/c/xdqv

+0

.. gentil! Merci .. –

+0

Essayez celui-ci dans votre benchmarker: var n: int = ((Math.random() * 0x7FFFFFFF) &2)-1; –

+0

Il n'y a rien de spécial à propos de 0x7FFFFFFF, en fait pour obtenir une propagation égale, Math.random() devrait probablement être multiplié par une puissance de deux qui est 4 ou plus: 4, 8, 16, etc ... tel que le deuxième bit est 1 aussi souvent que 0. –