Randomize float using arc4random?

2019-04-01 23:57发布

问题:

I have a float and I am trying to get a random number between 1.5 - 2. I have seen tutorials on the web but all of them are doing the randomization for 0 to a number instead of 1.5 in my case. I know it is possible but I have been scratching my head on how to actually accomplish this. Can anyone help me?

Edit1: I found the following method on the web but I do not want all these decimals places. I only want things like 5.2 or 7.4 etc...

How would I adjust this method to do that?

-(float)randomFloatBetween:(float)num1 andLargerFloat:(float)num2
{
    int startVal = num1*10000;
    int endVal = num2*10000; 

    int randomValue = startVal + (arc4random() % (endVal - startVal));
    float a = randomValue;

    return (a / 10000.0);
}

Edit2: Ok so now my method is like this:

-(float)randomFloatBetween:(float)num1 andLargerFloat:(float)num2
{
    float range = num2 - num1;
    float val = ((float)arc4random() / ARC4RANDOM_MAX) * range + num1;
    return val;
}

Will this produce numbers like 1.624566 etc..? Because I only want say 1.5,1.6,1.7,1.8,1.9, and 2.0.

回答1:

You can just produce a random float from 0 to 0.5 and add 1.5.

EDIT:

You're on the right track. I would use the maximum random value possible as your divisor in order to get the smallest intervals you can between possible values, rather than this arbitrary division by 10,000 thing you have going on. So, define the maximum value of arc4random() as a macro (I just found this online):

#define ARC4RANDOM_MAX      0x100000000

Then to get a value between 1.5 and 2.0:

float range = num2 - num1;
float val = ((float)arc4random() / ARC4RANDOM_MAX) * range + num1;
return val;

This will also give you double precision if you want it (just replace float with double.)

EDIT AGAIN:

Yes, of course this will give you values with more than one decimal place. If you want only one, just produce a random integer from 15 to 20 and divide by 10. Or you could just hack off the extra places afterward:

float range = num2 - num1;
float val = ((float)arc4random() / ARC4RANDOM_MAX) * range + num1;
int val1 = val * 10;
float val2= (float)val1 / 10.0f;
return val2;


回答2:

arc4random is a 32-bit generator. It generates Uint32's. The maximum value of arc4random() is UINT_MAX. (Do not use ULONG_MAX!)

The simplest way to do this is:

// Generates a random float between 0 and 1
inline float randFloat()
{
  return (float)arc4random() / UINT_MAX ;
}

// Generates a random float between imin and imax
inline float randFloat( float imin, float imax )
{
  return imin + (imax-imin)*randFloat() ;
}

// between low and (high-1)
inline float randInt( int low, int high )
{
  return low + arc4random() % (high-low) ; // Do not talk to me
  // about "modulo bias" unless you're writing a casino generator
  // or if the "range" between high and low is around 1 million.
}


回答3:

This should work for you:

float mon_rand() {
  const u_int32_t r = arc4random();
  const double Min = 1.5;

  if (0 != r) {
    const double rUInt32Max = 1.0 / UINT32_MAX;
    const double dr = (double)r;
    /* 0...1 */
    const double nr = dr * rUInt32Max;
    /* 0...0.5 */
    const double h = nr * 0.5;
    const double result = Min + h;
    return (float)result;
  }
  else {
    return (float)Min;
  }
}


回答4:

That was the simplest I could think of, when I had the same "problem" and it worked for me:

// For values from 0.0 to 1.0
float n;

n = (float)((arc4random() % 11) * 0.1);

And in your case, from 1.5 to 2.0:

float n;

n = (float)((arc4random() % 6) * 0.1);
n += 15 * 0.1;


回答5:

For anybody who wants more digits:

If you just want float, instead of arc4random(3) it would be easier if you use rand48(3):

// Seed (only once)
srand48(arc4random()); // or time(NULL) as seed

double x = drand48();

The drand48() and erand48() functions return non-negative, double-precision, floating-point values, uniformly distributed over the interval [0.0 , 1.0].

Taken from this answer.