Round Float Value - objective-c

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;

Related

What is the most efficient way to get a random odd or even number?

So off the top of my head, I can think of a few solutions (focusing on getting random odd numbers for example):
int n;
while (n == 0 || n % 2 == 0) {
n = (arc4random() % 100);
}
eww.. right? Not efficient at all..
int n = arc4random() % 100);
if (n % 2 == 0) n += 1;
But I don't like that it's always going to increase the number if it's not odd.. Maybe that shouldn't matter? Another approach could be to randomize that:
int n = arc4random() % 100);
if (n % 2 == 0) {
if (arc4random() % 2 == 0) {
n += 1;
else {
n -= 1;
}
}
But this feels a little bleah to me.. So I am wondering if there is a better way to do this sort of thing?
Generate a random number and then multiply it by two for even, multiply by two plus 1 for odd.
In general, you want to keep these simple or you run the risk of messing up the distribution of numbers. Take the output of the typical [0...1) random number generator and then use a function to map it to the desired range.
FWIW - It doesn't look like you're skewing the distributions above, except for the third one. Notice that getting 99 is less probable than all the others unless you do your adjustments with a modulus incl. negative numbers. Since..
P(99) = P(first roll = 99) + P(first roll = 100 & second roll = -1) + P(first roll = 98 & second roll = +1)
and P(first roll = 100) = 0
If you want a random set of binary digits followed by a fixed digit, then I'd go with bitwise operations:
odd = arc4random() | 1;
even = arc4random() & ~ 1;

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

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