Arithmetic/Rational/Objective-C: Difference between revisions

From Rosetta Code
Content added Content deleted
m (prepare for inclusion as template)
m (modernize)
Line 11: Line 11:
BOOL withSign;
BOOL withSign;
}
}
+(RCRationalNumber *)valueWithNumerator:(int)num andDenominator: (int)den;
+(instancetype)valueWithNumerator:(int)num andDenominator: (int)den;
+(RCRationalNumber *)valueWithDouble: (double)fnum;
+(instancetype)valueWithDouble: (double)fnum;
+(RCRationalNumber *)valueWithInteger: (int)inum;
+(instancetype)valueWithInteger: (int)inum;
+(RCRationalNumber *)valueWithRational: (RCRationalNumber *)rnum;
+(instancetype)valueWithRational: (RCRationalNumber *)rnum;
-(instancetype)initWithNumerator: (int)num andDenominator: (int)den;
-(id)init;
-(id)initWithNumerator: (int)num andDenominator: (int)den;
-(instancetype)initWithDouble: (double)fnum precision: (int)prec;
-(instancetype)initWithInteger: (int)inum;
-(id)initWithDouble: (double)fnum precision: (int)prec;
-(instancetype)initWithRational: (RCRationalNumber *)rnum;
-(id)initWithInteger: (int)inum;
-(id)initWithRational: (RCRationalNumber *)rnum;
-(NSComparisonResult)compare: (RCRationalNumber *)rnum;
-(NSComparisonResult)compare: (RCRationalNumber *)rnum;
-(id)simplify: (BOOL)act;
-(id)simplify: (BOOL)act;
Line 63: Line 62:
@implementation RCRationalNumber
@implementation RCRationalNumber
// initializers
// initializers
-(id)init
-(instancetype)init
{
{
NSLog(@"initialized to unity");
NSLog(@"initialized to unity");
Line 69: Line 68:
}
}


-(id)initWithNumerator: (int)num andDenominator: (int)den
-(instancetype)initWithNumerator: (int)num andDenominator: (int)den
{
{
if ((self = [super init]) != nil) {
if ((self = [super init]) != nil) {
Line 85: Line 84:
}
}


-(id)initWithInteger:(int)inum
-(instancetype)initWithInteger:(int)inum
{
{
return [self initWithNumerator: inum andDenominator: 1];
return [self initWithNumerator: inum andDenominator: 1];
}
}


-(id)initWithDouble: (double)fnum precision: (int)prec
-(instancetype)initWithDouble: (double)fnum precision: (int)prec
{
{
if ( prec > 9 ) prec = 9;
if ( prec > 9 ) prec = 9;
Line 98: Line 97:
}
}


-(id)initWithRational: (RCRationalNumber *)rnum
-(instancetype)initWithRational: (RCRationalNumber *)rnum
{
{
return [self initWithNumerator: [rnum numerator] andDenominator: [rnum denominator]];
return [self initWithNumerator: [rnum numerator] andDenominator: [rnum denominator]];
Line 211: Line 210:
}
}


// or just test if negativ
// or just test if negative
-(BOOL)isNegative
-(BOOL)isNegative
{
{
return ([self numerator] < 0) ? YES : NO;
return [self numerator] < 0;
}
}


Line 253: Line 252:


// class method
// class method
+(RCRationalNumber *)valueWithNumerator:(int)num andDenominator: (int)den
+(instancetype)valueWithNumerator:(int)num andDenominator: (int)den
{
{
return [[[RCRationalNumber alloc] initWithNumerator: num andDenominator: den] autorelease];
return [[self alloc] initWithNumerator: num andDenominator: den];
}
}


+(RCRationalNumber *)valueWithDouble: (double)fnum
+(instancetype)valueWithDouble: (double)fnum
{
{
return [[[RCRationalNumber alloc] initWithDouble: fnum] autorelease];
return [[self alloc] initWithDouble: fnum];
}
}


+(RCRationalNumber *)valueWithInteger: (int)inum
+(instancetype)valueWithInteger: (int)inum
{
{
return [[[RCRationalNumber alloc] initWithInteger: inum] autorelease];
return [[self alloc] initWithInteger: inum];
}
}


+(RCRationalNumber *)valueWithRational: (RCRationalNumber *)rnum
+(instancetype)valueWithRational: (RCRationalNumber *)rnum
{
{
return [[[RCRationalNumber alloc] initWithRational: rnum] autorelease];
return [[self alloc] initWithRational: rnum];
}
}
@end</lang>
@end</lang>
Line 280: Line 279:
int main()
int main()
{
{
@autoreleasepool {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];


int i;
int i;
for(i=2; i < 0x80000; i++) {
for(i=2; i < 0x80000; i++) {
int candidate = i;
int candidate = i;
RCRationalNumber *sum = [RCRationalNumber valueWithNumerator: 1
RCRationalNumber *sum = [RCRationalNumber valueWithNumerator: 1
andDenominator: candidate];
andDenominator: candidate];
int factor;
int factor;
for(factor=2; factor < sqrt((double)candidate); factor++) {
for(factor=2; factor < sqrt((double)candidate); factor++) {
if ( (candidate % factor) == 0 ) {
if ( (candidate % factor) == 0 ) {
sum = [[sum add: [RCRationalNumber valueWithNumerator: 1
sum = [[sum add: [RCRationalNumber valueWithNumerator: 1
andDenominator: factor]]
andDenominator: factor]]
add: [RCRationalNumber valueWithNumerator: 1
add: [RCRationalNumber valueWithNumerator: 1
andDenominator: (candidate/factor)]];
andDenominator: (candidate/factor)]];
}
}
if ( [sum denominator] == 1 ) {
printf("Sum of recipr. factors of %d = %d exactly %s\n",
candidate, [sum integer], ([sum integer]==1) ? "perfect!" : "");
}
}
}
}
if ( [sum denominator] == 1 ) {
printf("Sum of recipr. factors of %d = %d exactly %s\n",
candidate, [sum integer], ([sum integer]==1) ? "perfect!" : "");
}
}


}
[pool release];
return 0;
return 0;
}</lang>
}</lang>

Revision as of 09:13, 25 February 2014

Arithmetic/Rational/Objective-C is part of Rational Arithmetic. You may find other members of Rational Arithmetic at Category:Rational Arithmetic.
File frac.h

<lang objc>#import <Foundation/Foundation.h>

@interface RCRationalNumber : NSObject {

@private
 int numerator;
 int denominator;
 BOOL autoSimplify;
 BOOL withSign;

} +(instancetype)valueWithNumerator:(int)num andDenominator: (int)den; +(instancetype)valueWithDouble: (double)fnum; +(instancetype)valueWithInteger: (int)inum; +(instancetype)valueWithRational: (RCRationalNumber *)rnum; -(instancetype)initWithNumerator: (int)num andDenominator: (int)den; -(instancetype)initWithDouble: (double)fnum precision: (int)prec; -(instancetype)initWithInteger: (int)inum; -(instancetype)initWithRational: (RCRationalNumber *)rnum; -(NSComparisonResult)compare: (RCRationalNumber *)rnum; -(id)simplify: (BOOL)act; -(void)setAutoSimplify: (BOOL)v; -(void)setWithSign: (BOOL)v; -(BOOL)autoSimplify; -(BOOL)withSign; -(NSString *)description; // ops -(id)multiply: (RCRationalNumber *)rnum; -(id)divide: (RCRationalNumber *)rnum; -(id)add: (RCRationalNumber *)rnum; -(id)sub: (RCRationalNumber *)rnum; -(id)abs; -(id)neg; -(id)mod: (RCRationalNumber *)rnum; -(int)sign; -(BOOL)isNegative; -(id)reciprocal; // getter -(int)numerator; -(int)denominator; //setter -(void)setNumerator: (int)num; -(void)setDenominator: (int)num; // defraction -(double)number; -(int)integer; @end</lang>

File frac.m

<lang objc>#import <Foundation/Foundation.h>

  1. import <math.h>
  2. import "frac.h"

// gcd: Greatest common divisor#Recursive_Euclid_algorithm // if built in as "private" function, add static.

static int lcm(int a, int b) {

 return a / gcd(a,b) * b;

}

@implementation RCRationalNumber // initializers -(instancetype)init {

 NSLog(@"initialized to unity");
 return [self initWithInteger: 1];

}

-(instancetype)initWithNumerator: (int)num andDenominator: (int)den {

 if ((self = [super init]) != nil) {
   if (den == 0) {
     NSLog(@"denominator is zero");
     return nil;
   }
   [self setNumerator: num];
   [self setDenominator: den];
   [self setWithSign: YES];
   [self setAutoSimplify: YES];
   [self simplify: YES];
 }
 return self;

}

-(instancetype)initWithInteger:(int)inum {

 return [self initWithNumerator: inum andDenominator: 1];

}

-(instancetype)initWithDouble: (double)fnum precision: (int)prec {

 if ( prec > 9 ) prec = 9;
 double p = pow(10.0, (double)prec);
 int nd = (int)(fnum * p);
 return [self initWithNumerator: nd andDenominator: (int)p ];

}

-(instancetype)initWithRational: (RCRationalNumber *)rnum {

 return [self initWithNumerator: [rnum numerator] andDenominator: [rnum denominator]];

}

// comparing -(NSComparisonResult)compare: (RCRationalNumber *)rnum {

 if ( [self number] > [rnum number] ) return NSOrderedDescending;
 if ( [self number] < [rnum number] ) return NSOrderedAscending;
 return NSOrderedSame;

}

// string rapresentation of the Q -(NSString *)description {

 [self simplify: [self autoSimplify]];
 return [NSString stringWithFormat: @"%@%d/%d", [self isNegative] ? @"-" : 

( [self withSign] ? @"+" : @"" ), abs([self numerator]), [self denominator]]; }

// setter options -(void)setAutoSimplify: (BOOL)v {

 autoSimplify = v;
 [self simplify: v];

} -(void)setWithSign: (BOOL)v {

 withSign = v;

}

// getter for options -(BOOL)autoSimplify {

 return autoSimplify;

}

-(BOOL)withSign {

 return withSign;

}

// "simplify" the fraction ... -(id)simplify: (BOOL)act {

 if ( act ) {
   int common = gcd([self numerator], [self denominator]);
   [self setNumerator: [self numerator]/common];
   [self setDenominator: [self denominator]/common];
 }
 return self;

}

// diadic operators -(id)multiply: (RCRationalNumber *)rnum {

 int newnum = [self numerator] * [rnum numerator];
 int newden = [self denominator] * [rnum denominator];
 return [RCRationalNumber valueWithNumerator: newnum

andDenominator: newden]; }

-(id)divide: (RCRationalNumber *)rnum {

 return [self multiply: [rnum reciprocal]];

}

-(id)add: (RCRationalNumber *)rnum {

 int common = lcm([self denominator], [rnum denominator]);
 int resnum = common / [self denominator] * [self numerator] +
   common / [rnum denominator] * [rnum numerator];
 return [RCRationalNumber valueWithNumerator: resnum andDenominator: common];

}

-(id)sub: (RCRationalNumber *)rnum {

 return [self add: [rnum neg]];

}

-(id)mod: (RCRationalNumber *)rnum {

 return [[self divide: rnum] 

sub: [RCRationalNumber valueWithInteger: [[self divide: rnum] integer]]]; }

// unary operators -(id)neg {

 return [RCRationalNumber valueWithNumerator: -1*[self numerator]

andDenominator: [self denominator]]; }

-(id)abs {

 return [RCRationalNumber valueWithNumerator: abs([self numerator])

andDenominator: [self denominator]]; }

-(id)reciprocal {

 return [RCRationalNumber valueWithNumerator: [self denominator]

andDenominator: [self numerator]]; }

// get the sign -(int)sign {

 return ([self numerator] < 0) ? -1 : 1;

}

// or just test if negative -(BOOL)isNegative {

 return [self numerator] < 0;

}

// Q as real floating point -(double)number {

 return (double)[self numerator] / (double)[self denominator];

}

// Q as (truncated) integer -(int)integer {

 return [self numerator] / [self denominator];

}

// set num and den indipendently, fixing sign accordingly -(void)setNumerator: (int)num {

 numerator = num;

}

-(void)setDenominator: (int)num {

 if ( num < 0 ) numerator = -numerator;
 denominator = abs(num);

}

// getter -(int)numerator {

 return numerator;

}

-(int)denominator {

 return denominator;

}

// class method +(instancetype)valueWithNumerator:(int)num andDenominator: (int)den {

 return [[self alloc] initWithNumerator: num andDenominator: den];

}

+(instancetype)valueWithDouble: (double)fnum {

 return [[self alloc] initWithDouble: fnum];

}

+(instancetype)valueWithInteger: (int)inum {

 return [[self alloc] initWithInteger: inum];

}

+(instancetype)valueWithRational: (RCRationalNumber *)rnum {

 return [[self alloc] initWithRational: rnum];

} @end</lang>

Testing

<lang objc>#import <Foundation/Foundation.h>

  1. import "frac.h"
  2. import <math.h>

int main() {

 @autoreleasepool {
   int i;
   for(i=2; i < 0x80000; i++) {
     int candidate = i;
     RCRationalNumber *sum = [RCRationalNumber valueWithNumerator: 1
			                            andDenominator: candidate];
     int factor;
     for(factor=2; factor < sqrt((double)candidate); factor++) {
       if ( (candidate % factor) == 0 ) {
	  sum = [[sum add: [RCRationalNumber valueWithNumerator: 1

andDenominator: factor]] add: [RCRationalNumber valueWithNumerator: 1 andDenominator: (candidate/factor)]];

       }
     }
     if ( [sum denominator] == 1 ) {
       printf("Sum of recipr. factors of %d = %d exactly %s\n",

candidate, [sum integer], ([sum integer]==1) ? "perfect!" : "");

     }
   }
 }
 return 0;

}</lang>