星期日, 十二月 14, 2008

[Objective-C]分数类

// FILE FractionNumber.h

#import



@interface FractionNumber : NSObject {

int numerator;

int denominator;

}


@property(readwrite) int numerator, denominator;


-(id)initWithIntegers:(int)x numbery:(int)y;


- (NSString *)stringValue;

- (float)floatValue;

- (double)doubleValue;


- (void)add:(FractionNumber *)fn;

- (void)sub:(FractionNumber *)fn;

- (void)div:(FractionNumber *)fn;

- (void)mul:(FractionNumber *)fn;


+(int)gcd:(int)x numbery:(int)y;

+(int)lcm:(int)x numbery:(int)y;


+ (FractionNumber *)parseFractionNumberWithString:(NSString *)stringNumber;

+ (FractionNumber *)parseFractionNumberWithFloat:(double)floatNumber;

+ (FractionNumber *)parseFractionNumberWithInteger:(int)intNumber;


@end



// FILE FractionNumber.m

#import "FractionNumber.h"



@implementation FractionNumber


@synthesize numerator, denominator;


-(id)init

{

[super init];

numerator = 0;

denominator = 1;

return self;

}


-(id)initWithIntegers:(int)x numbery:(int)y

{

[super init];

numerator = x;

denominator = y;

return self;

}


- (NSString *)stringValue

{

return [[NSString alloc] initWithFormat:@"%.11g", [self doubleValue]];

}


- (float)floatValue

{

return (float)numerator/(float)denominator;

}


- (double)doubleValue

{

return (double)numerator/(double)denominator;

}


- (id)copy

{

FractionNumber *fn = [[FractionNumber alloc] initWithIntegers:numerator numbery:denominator];


return fn;

}



- (void)add:(FractionNumber *)fn

{

int x1 = numerator;

int y1 = denominator;

int x2 = [fn numerator];

int y2 = [fn denominator];

int lcmnum = [FractionNumber lcm:y1 numbery:y2];

x1 = lcmnum / y1 * x1;

x2 = lcmnum / y2 * x2;

numerator = x1 + x2;

denominator = lcmnum;

int gcdnum = [FractionNumber gcd:numerator numbery:denominator];

while (gcdnum > 1)

{

numerator /= gcdnum;

denominator /= gcdnum;

gcdnum = [FractionNumber gcd:numerator numbery:denominator];

}

}

- (void)sub:(FractionNumber *)fn

{

int x1 = numerator;

int y1 = denominator;

int x2 = [fn numerator];

int y2 = [fn denominator];

int lcmnum = [FractionNumber lcm:y1 numbery:y2];

x1 = lcmnum / y1 * x1;

x2 = lcmnum / y2 * x2;

numerator = x1 - x2;

denominator = lcmnum;

int gcdnum = [FractionNumber gcd:numerator numbery:denominator];

while (gcdnum > 1)

{

numerator /= gcdnum;

denominator /= gcdnum;

gcdnum = [FractionNumber gcd:numerator numbery:denominator];

}

}

- (void)div:(FractionNumber *)fn

{

FractionNumber *newFn = [[FractionNumber alloc] initWithIntegers:[fn denominator] numbery:[fn numerator]];

[self mul:newFn];

[newFn release];

}

- (void)mul:(FractionNumber *)fn

{

int x1 = numerator;

int y1 = denominator;

int x2 = [fn numerator];

int y2 = [fn denominator];

int gcdnum = [FractionNumber gcd:x1 numbery:y2];

while(gcdnum > 1)

{

x1 /= gcdnum;

y2 /= gcdnum;

gcdnum = [FractionNumber gcd:x1 numbery:y2];

}

gcdnum = [FractionNumber gcd:x2 numbery:y1];

while(gcdnum > 1)

{

x2 /= gcdnum;

y1 /= gcdnum;

gcdnum = [FractionNumber gcd:x2 numbery:y1];

}

numerator = x1 * x2;

denominator = y1 * y2;

}



+(int)gcd:(int)x numbery:(int)y

{

return (!y)?x:[self gcd:y numbery:x%y];

}

+(int)lcm:(int)x numbery:(int)y

{

int y1 = x;

int y2 = y;

int gcdnum = [FractionNumber gcd:y1 numbery:y2];

while(gcdnum > 1)

{

y1 /= gcdnum;

y2 /= gcdnum;

gcdnum = [FractionNumber gcd:y1 numbery:y2];

}

return x * y1;

}


+(FractionNumber *)parseFractionNumberWithString:(NSString *)stringNumber

{

if (!stringNumber || [stringNumber length] == 0)

return NULL;

NSRange range = [stringNumber rangeOfString:@"."];

if (range.location == NSNotFound)

{

int number = [stringNumber intValue];

return [FractionNumber parseFractionNumberWithInteger:number];

}

else

{

@try {

[stringNumber doubleValue];

}

@catch (NSException * e) {

@throw e;

}

int floatNumberLength = [stringNumber length] - range.location - 1;

int ten = pow(10, floatNumberLength);

NSArray *numberparts = [stringNumber componentsSeparatedByString:@"."];

int x = [(NSString *)[numberparts objectAtIndex:1] intValue];

//x = (x * (ten - 1) + x);

//int y = ((ten - 1) * ten);

int y = ten;

int gcdnum = [FractionNumber gcd:x numbery:y];

while (gcdnum > 1)

{

x /= gcdnum;

y /= gcdnum;

gcdnum = [FractionNumber gcd:x numbery:y];

}

int num = [(NSString *)[numberparts objectAtIndex:0] intValue];

x += num * y;


FractionNumber *fn = [[FractionNumber alloc] initWithIntegers:x numbery:y];

return fn;

}

}


+(FractionNumber *)parseFractionNumberWithFloat:(double)floatNumber

{

NSString *numberString = [[NSString alloc] initWithFormat:@"%.11g", floatNumber];

FractionNumber *fn = [FractionNumber parseFractionNumberWithString:numberString];

[numberString release];

return fn;

}


+(FractionNumber *)parseFractionNumberWithInteger:(int)intNumber

{

FractionNumber *fn = [[FractionNumber alloc] initWithIntegers:intNumber numbery:1];


return fn;

}


@end