How to create a random float in Objective-C? - 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];

Related

Round Float Value

is there any way to display only the first two numbers of a int?
490009423985
Result 49
i need only the 49. Any way to do this? i can split the int in characters, but i think theres a better way to do this
best regards
Here's a version without a loop:
uint64_t value = 490009423985;
int result = floor(value / pow(10, ceil(log10(value)) - 2));
use log10 to figure out how many digits and then use int devision to remove digits
like this
int digits = 2;
unsigned long long n = 490009423985;
for (int i = log10(n) - digits; i >= 0; --i) n /= 10;

Rounding a float number in objective-c

I want to know if there is a simple function that I can use such this sample.
I have a
float value = 1.12345;
I want to round it with calling something like
float value2 = [roundFloat value:value decimal:3];
NSLog(#"value2 = %f", value2);
And I get "1.123"
Is there any Library or default function for that or I should write a code block for this type of calculations?
thank for your help in advance
Using NSLog(#"%f", theFloat) always outputs six decimals, for example:
float theFloat = 1;
NSLog(#"%f",theFloat);
Output:
1.000000
In other words, you will never get 1.123 by using NSLog(#"%f", theFloat).
Cut-off after three decimals:
float theFloat = 1.23456;
float newFLoat = (int)(theFloat * 1000.0) / 1000.0;
NSLog(#"%f",newFLoat);
Output:
1.234000
Round to three decimals (using roundf() / lroundf() / ceil() / floor()):
float theFloat = 1.23456;
float newFLoat = (int)(roundf(theFloat * 1000.0)) / 1000.0;
NSLog(#"%f",newFLoat);
Output:
1.235000
Round to three decimals (dirty way):
float theFloat = 1.23456;
NSString *theString = [NSString stringWithFormat:#"%.3f", theFloat];
float newFloat = [theString floatValue];
NSLog(#"%#",theString);
NSLog(#"%f",newFloat);
Output:
1.235
1.235000
For printing the value use:
NSLog(#"value2 = %.3f", value2);
Rounding to 3 decimal digits before calculations doesn't really make sense because float is not a precise number. Even if you round it to 1.123, it will be something like 1.122999999998.
Rules:
Usually you round up only to print the result - string formatter can handle it (see above).
For precise calculations (e.g. currency), don't use floating point, use NSDecimalNumber or fixed point arithmetics.
Floating point numbers don't have decimal places, they have binary places. Decimal-radix numbers have decimal places. You can't round floating point numbers to specific numbers of decimal places unless you convert to a decimal radix. No routine, method, function etc., that returns a floating point value can possibly carry out this task.
Note that "Round" is not necessarily as simple a topic as you think. For example
DIY Calculator: Rounding Algorithms 101 lists 16 different methods for rounding a number.
Wikipedia:Rounding covers a lot of the same ground
And Cplusplus has source code for a bunch of Rounding Algorithms that are easy translatable to objective-c
How you want to round will depend on the context of what you are doing with for data.
And I should point out that Stack Overflow already has a plethora of other questions about rounding in objective-c
//Your Number to Round (can be predefined or whatever you need it to be)
float numberToRound = 1.12345;
float min = ([ [[NSString alloc]initWithFormat:#"%.0f",numberToRound] floatValue]);
float max = min + 1;
float maxdif = max - numberToRound;
if (maxdif > .5) {
numberToRound = min;
}else{
numberToRound = max;
}
//numberToRound will now equal it's closest whole number (in this case, it's 1)
Here is a simple way to do it:
float numberToRound = 1.12345f;
float remainder = numberToRound*1000.0f - (float)((int)(numberToRound*1000.0f));
if (remainder >= 0.5f) {
numberToRound = (float)((int)(numberToRound*1000.0f) + 1)/1000.0f;
}
else {
numberToRound = (float)((int)(numberToRound*1000.0f))/1000.0f;
}
For an arbitrary decimal place, substitute 1000.0f in the above code with
float mult = powf(10.0f, decimal);
try
#import <math.h>
float cutFloat( float number, int decimal) {
number = number*( pow(10,decimal) );
number = (int)number;
number = number/( pow(10,decimal) ) ;
return number;
}

Randomize float using arc4random?

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.

round number 105 or 95 to 100 in objective c

I have integer value, and need to round it, how to do that?
105 will be 110
103 will be 100
so classical rounding for decimals? thank you!
One more for you:
int originalNumber = 95; // or whatever
int roundedNumber = 10 * ((originalNumber + 5)/10);
Integer division always truncates in C, so e.g. 3/4 = 0, 4/4 = 1.
I don't know the exact Objective-C syntax, byt general programming question. C-style:
int c = 105;
if (c % 10 >= 5) {
c += 10;
}
c -= c % 10;
No floating point calculations required.
One way to solve this:
rounded = (value + 5) - ((value + 5) % 10);
Or slightly modified:
rounded = value + 5;
rounded -= rounded % 10;
See here: Rounding numbers in Objective-C
You could support floats or express your ints as floats (105.0).

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;