Divide int's and round up in Objective-C - 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{
}

Related

Unable to calculate the sum of prime numbers below 2 million

I'm doing the Euler's Method project to find the sum of prime numbers below 2 million and I'm struggling. Here is the code I'm using. When I calculate the sum below 10 and the sum below 50 I'm getting the right value, but where I'm calculating the sum below 2 million project Euler is saying my solution is incorrect. Any ideas?
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
#autoreleasepool {
int p = 2, d, total;
BOOL isPrime;
total = 0;
NSLog(#"%i ", p);
for ( p = 3; p < 2e6; p += 2){
isPrime = YES;
for ( d = 3; isPrime == YES && d < p; d += 2)
if ( p % d == 0)
isPrime = NO;
if (isPrime == YES){
NSLog(#"%i ", p);
total += p ;}
}
NSLog(#"total = %i", total + 2);
}
return 0;
}
This function sums the primes less than n using the Sieve of Eratosthenes:
function sumPrimes(n)
sum := 0
sieve := makeArray(2..n, True)
for p from 2 to n step 1
if sieve[p]
sum := sum + p
for i from p * p to n step p
sieve[i] := False
return sum
I'll leave it to you to translate to Objective-C with a suitable data type. For n = 2000000, this should run in one or two seconds.
There are a couple of mistakes. The first being that you're overflowing. Use a long instead of an int. The second thing is just a performance boost. Change your for loop from p < 2e6, to p*p <= 2e6. This way you rule out all numbers above the square root of 2e6. Fix those problems and you'll be good to go. Good luck!

Simplifying a fraction with decimals for ratio calculation [duplicate]

As part of a calculator app, I am trying to implement uses with sigma notation. However, the result it prints out is always a decimal, and the rest isn't important. I simply want to change the decimal to a fraction.
I already have the reduce function, the problem I'm having is getting from a decimal like this: '0.96875' to it's fractional value, '31/32'
Thanks!
PS: I've looked into just about everything, and for the life of me, I can't figure this out. All I need at this point is how to take the decimal out of it, and I can then reduce it.
Here is my reduce method:
-(void)reduce {
int u = numerator;
int v = denominator;
int temp;
while (v != 0) {
temp = u % v;
u = v;
v = temp;
}
numerator /= u;
denominator /= u;
}
Found this out myself. What I did was multiply the numerator and denominator by 1000000 (recalling that the decimal looked like .96875/1) so that it looked like 96875/100000.
Then, I used this reduce method to bring it into lowest terms:
-(void)reduce {
int u = numerator;
int v = denominator;
int temp;
while (v != 0) {
temp = u % v;
u = v;
v = temp;
}
numerator /= u;
denominator /= u;
}
And finally,I used a print method to get it into fraction form:
//In the .h
#property int numerator, denominator, mixed;
-(void)print;
//In the .m
#synthesize numerator, denominator, mixed;
-(void)print {
if (numerator > denominator) {
//Turn fraction into mixed number
mixed = numerator/denominator;
numerator -= (mixed * denominator);
NSLog(#"= %i %i/%i", mixed, numerator, denominator);
} else if (denominator != 1) {
//Print fraction normally
NSLog(#"= %i/%i", numerator, denominator);
} else {
//Print as integer if it has a denominator of 1
NSLog(#"= %i", numerator);
}
}
And got my desired output:
31/32
I found a fairly good way of doing this a while back, although I don't recall where from. Anyway, it works recursively like this (this is pseudocode, not C):
function getRational(float n)
let i = floor(n); (the integer component of n)
let j = n - i;
if j < 0.0001 (use abritrary precision threshold here), return i/1
let m/n = getRational(1 / j)
return ((i * m) + n) / m
For example, take 3.142857 as a starting point.
i = 3
j = 0.142857
m/n = getRational(7)
i = 7
j = 0
return 7/1
m/n = 7/1
return ((3*7)+1) / 7 = 22/7
Or a more complicated example, 1.55:
i = 1
j = 0.55
m/n = getRational(1.81818181)
i = 1
j = 0.81818181
m/n = getRational(1.22222222)
i = 1
j = 0.22222222
m/n = getRational(4.5)
i = 4
j = 0.5
m/n = getRational(2)
i = 2
j = 0
return 2/1
m/n = 2/1
return ((4*2)+1)/2 = 9/2
m/n = 9/2
return ((1*9)+2)/9 = 11/9
m/n = 11/9
return ((1*11)+9)/11) = 20/11
m/n = 20/11
return ((1*20)+11)/20 = 31/20
I tried this with PI once. It would have gone on a while, but if you set your threshold to 0.01, it only goes down a few recursions before returning 355/113.
There's a bit of a gotcha that you might end up with integers that are too large if it goes down too deep when it returns; I haven't really looked into a good way of allowing for that, except setting the precision threshold to something fairly lax, such as 0.01.
Try this :
-(NSString *)convertToFraction:(CGFloat)floatValue{
double tolerance = 1.0E-6;
CGFloat h1 = 1;
CGFloat h2 = 0;
CGFloat k1 = 0;
CGFloat k2 = 1;
CGFloat b = floatValue;
do{
CGFloat a = floor(b);
CGFloat aux = h1;
h1 = a*h1+h2;
h2 = aux;
aux = k1;
k1 = a*k1+k2;
k2 = aux;
b = 1/(b-a);
}while (ABS(floatValue-h1/k1) > floatValue*tolerance) ;
return k1 > 1 ? [NSString stringWithFormat:#"%.0f/%.0f",h1,k1] : [NSString stringWithFormat:#"%.0f",h1];
}

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