Randomize float using arc4random? - objective-c

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.

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;

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.
}

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;
}
}

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;

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.

Related

How to generate a random float number between 0 (included) and 1 (excluded)

With (float)arc4random() how can I generate a float random number included in [0, 1[ i.e. in the interval 0-1, with 0 included and 1 excluded?
My code is
do {
c = ((float)arc4random() / 0x100000000);
}
while (c == 1.0);
Is there anything better?
It depends how many possible numbers you want in between the two?
But you can use...
float numberOfPossibilities = ...;
float random = (float)arc4random_uniform(numberOfPossibilities) / numberOfPossibilities;
To exclude 1 you could do...
float random = (float)arc4random_uniform(numberOfPossibilities - 1) / numberOfPossibilities;
// Get a value greater than the greatest possible random choice
double one_over_max = UINT32_MAX + 1L;
// Use that as the denominator; this ratio will always be less than 1
double half_open_result = arc4random() / one_over_max;
The resolution -- the number of possible resulting values -- is thus the same as the resolution of the original random function. The gap between the largest result and the top of the interval is the difference between your chosen denominator and the original number of results, over the denominator. In this case, that's 1/4294967296; pretty small.
This is extension for Float Swift 3.1
// MARK: Float Extension
public extension Float {
/// Returns a random floating point number between 0.0 and 1.0, inclusive.
public static var random: Float {
return Float(arc4random()) / 0xFFFFFFFF
}
/// Random float between 0 and n-1.
///
/// - Parameter n: Interval max
/// - Returns: Returns a random float point number between 0 and n max
public static func random(min: Float, max: Float) -> Float {
return Float.random * (max - min) + min
}
}
you can use like:
Float num = (arc4random() % ([[filteredArrayofPerticularword count] FloatValue]));
In that filteredArrayofPerticularword array u can store your number.

Rounding an Objective-C float to the nearest .05

I want to round the following floating point numbers to the nearest 0.05.
449.263824 --> 449.25
390.928070 --> 390.90
390.878082 --> 390.85
How can I accomplish that?
The match the output in your question, you can do the following:
float customRounding(float value) {
const float roundingValue = 0.05;
int mulitpler = floor(value / roundingValue);
return mulitpler * roundingValue;
}
Example:
NSLog(#"Output: %f --> %.2f", 449.263824, customRounding(449.263824));
There's the round() function. I think you need to do this:
double rounded = round(number * 20.0) / 20.0;
As with all floating point operations, since 1/5 is not directly representable as a binary value, you'll see bizarre not quite exact results. If you don't like that, you can use NSDecimalNumber's -decimalNumberByRoundingAccordingToBehaviour: method but it'll be a bit slower.
I know the question is answered but I used the following code:
float unrounded = 2.234;
float decimal = 0.05;
float decimal2 = 1/decimal;
float rounded = (((int)((unrounded*decimal2)+0.5))/decimal2);
For example:
> unrounded = 2.234
> decimal = 0.05
> decimal2 = 1/0.05 = 20
>
> rounded:
> 2.234 * 20 = 44.68
> 44.68 + 0.5 = 45.18
> make an integer: 45
> 45 / 20 = 2.25
You could use an NSNumberFormatter to carry out rounding and indeed to specify the rounding you require via one of the NSNumberFormatterRoundingMode options. (Search for "NSNumberFormatterRoundingMode" in the above class reference to see the defaults.)
However, as #Jesse states in the comment on your question, there doesn't seems to be any standard form of rounding going on in the examples you're provided.
If it were round to the nearest x, then you could go with:
roundedValue = originalValue + x * 0.5;
roundedValue -= fmodf(roundedValue, x);
As it is, it isn't entirely clear what you want.
Use floor:
#include <math.h>
...
double result = floor(number * 20.0) / 20.0;

Divide int's and round up in Objective-C

I have 2 int's. How do I divide one by the other and then round up afterwards?
If your ints are A and B and you want to have ceil(A/B) just calculate (A+B-1)/B.
What about:
float A,B; // this variables have to be floats!
int result = floor(A/B); // rounded down
int result = ceil(A/B); // rounded up
-(NSInteger)divideAndRoundUp:(NSInteger)a with:(NSInteger)b
{
if( a % b != 0 )
{
return a / b + 1;
}
return a / b;
}
As in C, you can cast both to float and then round the result using a rounding function that takes a float as input.
int a = 1;
int b = 2;
float result = (float)a / (float)b;
int rounded = (int)(result+0.5f);
i
If you looking for
2.1 roundup> 3
double row = _datas.count / 3;
double rounded = ceil(_datas.count / 3);
if(row > rounded){
row += 1;
}else{
}

Divide integer by 16 without using division or cast

OKAY... let me rephrase this question...
How can I obtain x 16ths of an integer without using division or casting to double....
int res = (ref * frac) >> 4
(but worry a a bit about overflow. How big can ref and frac get? If it could overflow, cast to a longer integer type first)
In any operation of such kind it makes sense to multiply first, then divide. Now, if your operands are integers and you are using a compileable language (eg. C), use shr 4 instead of /16 - this will save some processor cycles.
Assuming everything here are ints, any optimizing compiler worth its salt will notice 16 is a power of two, and shift frac accordingly -- so long as optimizations are turned on. Worry more about major optimizations the compiler can't do for you.
If anything, you should bracket ref * frac and then have the divide, as any value of frac less than 16 will result in 0, whether by shift or divide.
You can use left shift or right shift:
public static final long divisionUsingMultiplication(int a, int b) {
int temp = b;
int counter = 0;
while (temp <= a) {
temp = temp<<1;
counter++;
}
a -= b<<(counter-1);
long result = (long)Math.pow(2, counter-1);
if (b <= a) result += divisionUsingMultiplication(a,b);
return result;
}
public static final long divisionUsingShift(int a, int b) {
int absA = Math.abs(a);
int absB = Math.abs(b);
int x, y, counter;
long result = 0L;
while (absA >= absB) {
x = absA >> 1;
y = absB;
counter = 1;
while (x >= y) {
y <<= 1;
counter <<= 1;
}
absA -= y;
result += counter;
}
return (a>0&&b>0 || a<0&&b<0)?result:-result;
}
I don't understand the constraint, but this pseudo code rounds up (?):
res = 0
ref= 10
frac = 2
denominator = 16
temp = frac * ref
while temp > 0
temp -= denominator
res += 1
repeat
echo res

How to create a random float in Objective-C?

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?
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;
}
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.
use arc4random() or seed your random values
try
float pscale = ((float)randn) / 100.0f;
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.
Easiest.
+ (float)randomNumberBetween:(float)min maxNumber:(float)max
{
return min + arc4random_uniform(max - min + 1);
}
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);
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.
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];