35

I'm trying to create a random float between 0.15 and 0.3 in Objective-C. The following code always returns 1:

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

What am I doing wrong?

mskfisher
  • 3,291
  • 4
  • 35
  • 48
Roman
  • 385
  • 1
  • 3
  • 6
  • this code seems to be working, still using 100.0f is better. Only case that I can guess is that you're putting this code in a function and not declaring it in .h, so the compiler could be upgrading it to double. – chunkyguy Jun 28 '11 at 23:40

8 Answers8

68

Here is a function

- (float)randomFloatBetween:(float)smallNumber and:(float)bigNumber {
    float diff = bigNumber - smallNumber;
    return (((float) (arc4random() % ((unsigned)RAND_MAX + 1)) / RAND_MAX) * diff) + smallNumber;
}
App Dev Guy
  • 5,396
  • 4
  • 31
  • 54
Boris
  • 689
  • 1
  • 5
  • 2
  • 14
    #define boris_random(smallNumber, bigNumber) ((((float) (arc4random() % ((unsigned)RAND_MAX + 1)) / RAND_MAX) * (bigNumber - smallNumber)) + smallNumber) – chunkyguy Jun 28 '11 at 23:24
  • @chunkyguy, Could you please rewrite this answer using `arc4random_uniform`? – Iulian Onofrei Jul 17 '15 at 12:19
21

Try this:

 (float)rand() / RAND_MAX

Or to get one between 0 and 5:

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

Several ways to do the same thing.

hasen
  • 161,647
  • 65
  • 194
  • 231
Caladain
  • 4,801
  • 22
  • 24
  • 21
    This is wrong. `random() / RAND_MAX` will not give you a floating-point value as neither value is floating-point. Also, the domain of `random()` is not 0 to RAND_MAX. The domain of `rand()` and `rand_r()` is. So you should use: `(float)rand() / RAND_MAX` to get the expected result. – Jonathan Grynspan Aug 04 '10 at 22:48
  • 1
    This is wrong (rand()/RAND_MAX) will give you a zero. Jonathan's comment is true. – Gorky Mar 02 '12 at 07:36
4
  1. use arc4random() or seed your random values
  2. try

    float pscale = ((float)randn) / 100.0f;
    
Lou Franco
  • 87,846
  • 14
  • 132
  • 192
3

Your code works for me, it produces a random number between 0.15 and 0.3 (provided I seed with srandom()). Have you called srandom() before the first call to random()? You will need to provide srandom() with some entropic value (a lot of people just use srandom(time(NULL))).

For more serious random number generation, have a look into arc4random, which is used for cryptographic purposes. This random number function also returns an integer type, so you will still need to cast the result to a floating point type.

dreamlax
  • 93,976
  • 29
  • 161
  • 209
2

Easiest.

+ (float)randomNumberBetween:(float)min maxNumber:(float)max
{
    return min + arc4random_uniform(max - min + 1);
}
jose920405
  • 7,982
  • 6
  • 45
  • 71
0

Using srandom() and rand() is unsafe when you need true randomizing with some float salt.

On MAC_10_7, IPHONE_4_3 and higher you can use arc4random_uniform(upper_bound)*. It allows to generate true random integer from zero to *upper_bound*.

So you can try the following

u_int32_t upper_bound = <some big enough integer>;

float r = 0.3 * (0.5 + arc4random_uniform(upper_bound)*1.0/upper_bound/2);
malex
  • 9,874
  • 3
  • 56
  • 77
0

To add to @Caladain's answer, if you want the solution to be as easy to use as rand(), you can define these:

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

Feel free to replace CGFloat with double if you don't have access to CoreGraphics.

Ky -
  • 30,724
  • 51
  • 192
  • 308
-5

I ended up generating to integers one for the actual integer and then an integer for the decimal. Then I join them in a string then I parse it to a floatvalue with the "floatValue" function... I couldn't find a better way and this works for my intentions, hope it helps :)

int integervalue = arc4random() % 2;
int decimalvalue = arc4random() % 9;   
NSString *floatString = [NSString stringWithFormat:@"%d.%d",integervalue,decimalvalue];
float randomFloat = [floatString floatValue];
melovje
  • 20
  • 2
  • 2
    This is an amazingly convoluted way to do a simple thing, and it's not even correct. (For example, it could never generate `1.01`.) – T.C. Jun 09 '14 at 19:28