views:

42

answers:

1

So im working on programming in objective c 2.0 book, and I'm working on a method to subtract 1 fraction object from another, I have the algorithm and everything set and it does work, but in going through the process (debugging) i found that even though i was copying the fractions into new instances so I wouldnt mess with the values in the original, the values of the numerator and denominator were still changing to reflect the values now assigned to the "working copies"

Not sure if I missed something here , any help or insight would be appreciated, (not really looking for feedback on the algorithm or my sloppy memory management)

Thanks,

Nick

oh yeah here's the implementation code:

    #import "Fraction.h"


@implementation Fraction


@synthesize numerator, denominator;




-(void) print
{

    NSLog (@"%i/%i", numerator, denominator);

}
-(void) setTo: (int) n over: (int) d
{

    numerator = n;

    denominator = d;
}
-(double) convertToNum
{

    if (denominator != 0)

        return (double) numerator / denominator;

    else

        return 1.0;
}
- (void) add: (Fraction *) f
{
    // To add two fractions:
    // a/b + c/d = ((a*d) + (b*c)) / (b * d)

    numerator = numerator * f.denominator

    + denominator * f.numerator;

    denominator = denominator * f.denominator;

    [self   reduce];
}
- (Fraction *) subtract: (Fraction *) f
{




    int x = denominator;
    int xhold = denominator;
    int y = [f denominator];
    int yHold = [f denominator];
    int temp1 = 1, temp2 = 0 ,  temp3 = 0, co1 = 1;


    Fraction *resultFraction = [[Fraction alloc] init]; 
    Fraction *xFraction = [[Fraction alloc] init];
    Fraction *yFraction = [[Fraction alloc] init];



    xFraction = self;
    yFraction = f;



        if ( x > y )

        {



            for (co1 = 1 ; temp1 != 0; co1++) 
                {


                    temp1 = x % y;

                    if (temp1 ==  0)

                    {

                    temp2 = x / y;

                    temp3 = y * temp2;

                        [yFraction setDenominator: temp3];

                        [yFraction setNumerator: [yFraction numerator] * temp2];

                        [xFraction setNumerator: [xFraction numerator] * co1];

                        [xFraction setDenominator:[xFraction denominator] * co1];

                    }

                    else if (temp1 !=0)


                        x = xhold * co1;


                }
            [xFraction setNumerator :  [ xFraction numerator] - [yFraction numerator] ];

            [xFraction  reduce];
            }
            else if ( y > x )
            {
                for (co1 = 1 ; temp1 != 0; co1++) 
            {

                temp1 = y % x;

                if (temp1 ==  0)
                    {

                    temp2 = y / x;

                    temp3 = x * temp2;

                    [yFraction setNumerator: [yFraction numerator] * co1];
                    [yFraction setDenominator: [yFraction denominator] * co1];

                    [xFraction  setNumerator: [xFraction numerator] * temp2];
                    [xFraction  setDenominator: temp3 ];
                    }
                else if (temp1 !=0)
                    y = yHold * co1 ;   
                }
            [xFraction setNumerator : [xFraction numerator] - [ yFraction numerator]];
                resultFraction = xFraction;
                [resultFraction reduce];
            }
        else if (x == y)
            {
    [xFraction setNumerator: [xFraction numerator] - [ yFraction numerator]];
                resultFraction = xFraction;
                [resultFraction reduce];
            }
    return resultFraction;
}
- (void) reduce
{

    int u = numerator;

    int v = denominator;

    int temp;

    while (v != 0) {

        temp = u % v;

        u = v;

        v = temp; 

    }
    numerator /= u;
    denominator /= u;
}
- (Fraction *) multiply : (Fraction *) f;
{
    Fraction *xFraction = [[Fraction alloc] init];
    Fraction *yFraction = [[Fraction alloc] init];
    Fraction *resultFraction = [[Fraction alloc] init];


    xFraction = self;
    yFraction = f;
    resultFraction = self;

    [resultFraction setNumerator: [xFraction numerator] * [yFraction numerator]];
    [resultFraction setDenominator: [xFraction denominator] * [yFraction denominator]];

    [resultFraction reduce];

    return resultFraction;
    }
@end
+3  A: 

Your -subtract: method contains this code:

Fraction *resultFraction = [[Fraction alloc] init]; 
Fraction *xFraction = [[Fraction alloc] init];
Fraction *yFraction = [[Fraction alloc] init];

xFraction = self;
yFraction = f;

The last two lines do not copy the values from self and f onto the new instances, they only copy the pointers (effectively losing/leaking the freshly allocated instances). After the last two lines xFraction points to the same object as self and yFraction points to the same object as f.

Since it does not look like you are implementing the NSCopying protocol, you will have to initialize your new instances by copying the values from the original instances. I have not really looked at your algorithm, but you might try this (instead of those last two assignments):

[xFraction setTo:numerator over:denominator];
[yFraction setTo:[f numerator] over:[f denominator]];
Chris Johnsen
Just to expand on the `NSCopying` protocol, the `Fraction` class could implement `copyWithZone:`, which would allow you to do this: `xFraction = [self copy]`
Tom Dalling
Awesome, haven't tried it but that makes 100% sense. Thanks so much for everybody who chimed in, I love this site!
nickthedude
worked like a charm, sweet.
nickthedude