2010-08-04 6 views
32

J'essaie de créer un flottement aléatoire entre 0,15 et 0,3 en Objective-C. Le code suivant renvoie toujours 1:Comment créer un flottant aléatoire en Objective-C?

int randn = (random() % 15)+15; 
float pscale = (float)randn/100; 

Qu'est-ce que je fais mal?

+0

ce code semble fonctionner, toujours en utilisant 100.0f est mieux. Seul le cas que je peux deviner est que vous mettez ce code dans une fonction et ne le déclarez pas en .h, donc le compilateur pourrait être en train de le mettre à jour en double. – chunkyguy

Répondre

17

Essayez ceci:

(float)rand()/RAND_MAX 

Ou pour obtenir un entre 0 et 5:

float randomNum = ((float)rand()/RAND_MAX) * 5; 

Plusieurs façons de faire la même chose.

+19

C'est faux. 'random()/RAND_MAX' ne vous donnera pas de valeur à virgule flottante car aucune valeur n'est à virgule flottante. En outre, le domaine de 'random()' n'est pas 0 à RAND_MAX. Le domaine de 'rand()' et 'rand_r()' est. Donc, vous devriez utiliser: '(float) rand()/RAND_MAX' pour obtenir le résultat attendu. –

+1

Ceci est faux (rand()/RAND_MAX) vous donnera un zéro. Le commentaire de Jonathan est vrai. – Gorky

+18

Vous savez que vous pouvez éditer des réponses, n'est-ce pas? – hasen

4
  1. utilisation arc4random() ou de graines de vos valeurs aléatoires
  2. essayer

    float pscale = ((float)randn)/100.0f; 
    
3

Votre code fonctionne pour moi, il produit un nombre aléatoire compris entre 0,15 et 0,3 (à condition que je graine avec srandom()). Avez-vous appelé srandom() avant le premier appel à random()? Vous devrez fournir srandom() avec une certaine valeur entropique (beaucoup de gens utilisent simplement srandom(time(NULL))). Pour une génération plus sérieuse de nombres aléatoires, jetez un coup d'œil sur arc4random, qui est utilisé à des fins de chiffrement. Cette fonction de nombre aléatoire renvoie également un type entier, de sorte que vous devrez toujours convertir le résultat en un type à virgule flottante.

63

est ici une fonction

- (float)randomFloatBetween:(float)smallNumber and:(float)bigNumber { 
float diff = bigNumber - smallNumber; 
return (((float) (arc4random() % ((unsigned)RAND_MAX + 1))/RAND_MAX) * diff) + smallNumber; 
} 
+13

#define boris_random (smallNumber, bigNumber) ((((flottant) (arc4random()% ((non signé) RAND_MAX + 1))/RAND_MAX) * (bigNumber - smallNumber)) + petitNumber) – chunkyguy

+0

@chunkyguy, Pourriez-vous s'il vous plaît réécrire cette réponse en utilisant 'arc4random_uniform'? –

0

En utilisant srandom() et rand() est dangereux quand vous avez besoin vrai randomizing avec un peu de sel de flotteur.

Sur MAC_10_7, IPHONE_4_3 et supérieur, vous pouvez utiliser arc4random_uniform (upper_bound) *. Il permet de générer un véritable nombre entier aléatoire de zéro à * upper_bound *.

Ainsi, vous pouvez essayer ce qui suit

u_int32_t upper_bound = <some big enough integer>; 

float r = 0.3 * (0.5 + arc4random_uniform(upper_bound)*1.0/upper_bound/2); 
-5

J'ai fini par générer des nombres entiers pour un nombre entier réel et un entier pour la décimale. Ensuite, je les rejoins dans une chaîne puis je l'analyse syntaxique à un floatValue avec la fonction « floatValue » ... Je ne pouvais pas trouver une meilleure façon et cela fonctionne pour mes intentions, espère que cela aide :)

int integervalue = arc4random() % 2; 
int decimalvalue = arc4random() % 9; 
NSString *floatString = [NSString stringWithFormat:@"%d.%d",integervalue,decimalvalue]; 
float randomFloat = [floatString floatValue]; 
+1

C'est une façon incroyablement compliquée de faire une chose simple, et ce n'est même pas correct. (Par exemple, il ne pourrait jamais générer '1.01'.) –

2

Le plus facile

+ (float)randomNumberBetween:(float)min maxNumber:(float)max 
{ 
    return min + arc4random_uniform(max - min + 1); 
} 
+1

' arc4random_uniform' génère un entier aléatoire. – Andy

0

Pour ajouter @ la réponse de Caladain, si vous voulez que la solution soit aussi facile à utiliser comme rand(), vous pouvez définir ces:

#define randf() ((CGFloat)rand()/RAND_MAX) 
#define randf_scaled(scale) (((CGFloat)rand()/RAND_MAX) * scale) 

Ne hésitez pas à remplacer CGFloat avec double si vous ne N'ont pas accès à CoreGraphics.

Questions connexes