0

Below is how I am formatting my picker currently. I would really like it to show 1/8 instead of 2/16 or 1/2 instead of 8/16. How can I adjust this to show my desired output? Thank you!

fractionArray = [[NSMutableArray alloc] init];
for(int frac = 0; frac <= 15; frac ++){ 
    NSString *fracString = [NSString stringWithFormat:@"%d/16", frac];
    [fractionArray addObject:fracString]; // Add the string.
Jason
  • 650
  • 2
  • 10
  • 33
  • 1
    possible duplicate of [Convert decimal to fraction in Objective-C?](http://stackoverflow.com/questions/5552537/convert-decimal-to-fraction-in-objective-c). See the second answer. – CodaFi Apr 24 '12 at 03:21
  • That's to convert a decimal, not a fraction...? – Jason Apr 24 '12 at 03:36
  • You can easily move to solution by getting the two necessary arguments with `-componentsSeparatedByString:`. Do not discount the value of that second answer so easily. – CodaFi Apr 24 '12 at 03:43
  • If you would be able to provide an example on that page, I will gladly close this post. I'm obviously not as advanced as you are. I learn by seeing the code, then understanding how it works. – Jason Apr 24 '12 at 04:03

2 Answers2

2

This should work for any power of 2 denominator:

// dodge this special case:
[fractionArray addObject:@"0"];

for ( int numerator = 1; numerator <= 15; numerator++ )
{
    int denominator = 16;
    int num = numerator;

    while ( num % 2 == 0 )
    {
        num /= 2;
        denominator /= 2;
    }

    NSString *fracString = [NSString stringWithFormat:@"%d/%d", num, denominator];
    [fractionArray addObject:fracString]; // Add the string.
}

And it's easy to extend this to any denominator. (Hint: replace 2 with n, iterate n from 2 up to sqrt(denominator).)

EDIT: actually works now!


Since I went ahead and coded it, here's the version that factors any denominator:

int denominator = 240;

for ( int numerator = 1; numerator < denominator; numerator++ )
{
    int denom = denominator;
    int num = numerator;
    int factor = 2;

    while ( factor * factor < denom )
    {
        while ( (num % factor) == 0 && (denom % factor) == 0 )
        {
            num /= factor;
            denom /= factor;
        }

        // don't worry about finding the next prime,
        // the loop above will skip composites
        ++factor; 
    }

    NSString *fracString = [NSString stringWithFormat:@"%d/%d", num, denom];
    [fractionArray addObject:fracString];
}
davehayden
  • 3,484
  • 21
  • 28
  • Crashes on NSString *fracString = [NSString stringWithFormat:@"%d/%d", numerator, denominator]; – Jason Apr 24 '12 at 04:00
  • Yup, boneheaded alright: if we divide numerator by 2 it goofs the loop. I'll edit the answer. :) – davehayden Apr 24 '12 at 06:09
  • @davehayden The top code works, but it displays as "0, 1/16, 1/8, 3/16, 1/4, 5/16, 3/8, 7/16, 1/2, 9/16, 5/8, 11/16, 3/4, 13/16, 7/8, 15/16, 1/16, 0, etc and then after 15/16 it shows 2/16. So after every inch, after the 15/16 it keeps going 3/16, 4/16 etc... – Jason Apr 26 '12 at 04:16
  • So I guess I wouldn't want a loop, since it only needs to run once...? – Jason Apr 26 '12 at 04:23
  • No, no, Rob Mayoff's got the right answer: just find the GCD (greatest common divisor) of the numerator and the denominator, then divide them both by that number. Faster, cleaner, better all around! – davehayden Apr 26 '12 at 05:34
  • @davehayden Im getting errors like crazy with Rob's answer, I don't even know where to begin to start fixing them. – Jason Apr 29 '12 at 20:00
2

Kids these days... Euclidean algorithm... what are they teaching in school... grumble grumble...

int gcd(int a, int b) {
    // assumes a >= 0 && b > 0
    while (b != 0) {
        int t = a % b;
        a = b;
        b = t;
    }
    return a;
}

NSString *stringByReducingFraction(int a, int b) {
    if (a == 0) return @"0";
    if (a == b) return @"1";

    int g = gcd(a, b);
    return [NSString stringWithFormat:@"%d/%d", a / g, b / g];
}
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • Ha! Of course! My excuse for not remembering that is I never wind up using gcd() for anything. GCD on the other hand is very useful. :) – davehayden Apr 25 '12 at 16:51
  • There are errors all over this code, I don't know where to start by fixing it. – Jason Apr 29 '12 at 20:02
  • There are no errors in the code I posted. I have put a complete working example, and its output, at https://gist.github.com/2553024. – rob mayoff Apr 29 '12 at 20:13
  • Ok, so how would I apply that to my code above? Because with yours I get 7 warnings and 7 errors. Don't even know where to start to fix them. – Jason Apr 29 '12 at 20:24
  • I am putting my code above in the viewDidLoad, is this my issue? – Jason Apr 29 '12 at 21:02
  • My code above defines two functions. You don't put function definitions inside method definitions. It sounds like you need to brush up on the basics of C and Objective-C. – rob mayoff Apr 29 '12 at 23:20
  • I've never taken any classes, I'm learning this all on my own and personal time. This site has provided more learning for me than any textbook I have read. I learn by seeing the code work, then I'm able to understand it more clearly. Thanks for your help! – Jason May 05 '12 at 15:05