Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

mdeh

macrumors 6502
Original poster
Jan 3, 2009
345
2
Based on the discussions about argument and return types in this chapter, modify both add: methods in the Fraction andComplex classes to take and return id objects. Then write a program that incorporates the following code sequence:
result = [dataValue1 add: dataValue2];
[result print];
where result, dataValue1, and dataValue2 are id objects. Make sure you set dataValue1 and dataValue2 appropriately in your program and free all objects before your program terminates.

Does this mean to modify EACH method so that EACH method can take a fraction or complex class object?
 

skochan

macrumors regular
Apr 1, 2006
150
0
California
Does this mean to modify EACH method so that EACH method can take a fraction or complex class object?

The Complex and Fraction classes both have add: methods. The exercise is to change the argument and return type of each add: method to take and return an id object.

Cheers,

Steve K.
 

mdeh

macrumors 6502
Original poster
Jan 3, 2009
345
2
Answer for 9-4???
Here is my attempt. Your input is appreciated.

Fraction.h
Code:
#import <Foundation/Foundation.h>
@interface Fraction : NSObject {
	int numerator;
	int denominator;
}
@property int numerator, denominator;
-(void) setTo: (int) n over: (int) d;
-(id) add: (id) f;
-(void) reduce;


Code:
#import "Fraction.h"


@implementation Fraction;
@synthesize denominator, numerator;
-(void) print 
{
	
	NSLog(@"%i/%i ", numerator, denominator);
}

-(void) setTo: (int) n over: (int) d
{
	numerator = n;
	denominator = d;
}


-(id) add: (id) f
{
	int resultNum, resultDenom;
	Fraction* result = [[Fraction alloc] init];
	
	resultNum = numerator *[ f denominator] + denominator * [f numerator];
	resultDenom = denominator *[ f denominator];
	
	[result setTo: resultNum over: resultDenom];
	[result reduce];
	return result;
}

-(double) convertToNum
{
	if (denominator != 0)
		return (double) numerator / denominator;
	else
		return 1.0;
}

-(void) reduce
{
	int u, v, temp;
	BOOL isNegativeNumerator = NO;
	BOOL isNegativeDenominator = NO;
	
	if ( numerator < 0)
	{
		isNegativeNumerator = YES;
		numerator = -numerator;
	}
	
	
	if ( denominator < 0)
	{
		isNegativeDenominator = YES;
		denominator = -denominator;
	}
	
	u = numerator;
	v = denominator;
	
	
	while (v != 0) {
		temp = u % v;
		u = v;
		v = temp;
	}
	
	
	
	numerator /= u;
	denominator /= u;
	
	
	
	if ( isNegativeNumerator == YES || isNegativeDenominator == YES)
		numerator = -numerator;
}

@end


Complex.h

Code:
#import <Foundation/Foundation.h>

@interface Complex : NSObject
{
	float real;
	float imaginary;
}

@property float real, imaginary;
-(id) add: (id) complexNumber; 
-(void) setReal: (float) r andImaginary: (float) i;
-(void) print;
@end

Complex.m

Code:
#import "Complex.h"
@implementation Complex

@synthesize real, imaginary;

-(void) setReal: (float) r andImaginary: (float) i
{
	real = r;
	imaginary = i;
}

-(id) add: (id) complexNumber
{
	Complex *myCx =  [[ Complex alloc ] init];
	myCx.real = (real + [complexNumber real]);
	myCx.imaginary = (imaginary + [complexNumber imaginary]);
	return myCx;
	
}
-(void) print
{
	NSLog(@"%g + %gi", real, imaginary);
}
@end

main.m

Code:
#import "Fraction.h"
#import "Complex.h"

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	id dataVal1, dataVal2, result;
	Complex *c1 = [[ Complex alloc] init];
	Complex *c2 = [[ Complex alloc] init];
	Fraction *f1 = [ [ Fraction alloc] init];
	Fraction *f2 = [ [ Fraction alloc] init];
	
	[c1 setReal: 67.0	andImaginary: 76.0];
	[c2 setReal: 27.0	andImaginary: 72.0];
	dataVal1 = c1;
	dataVal2 = c2;
	
	result = [dataVal1 add: dataVal2];
	[result print];
	
	[result release];
	
	[f1 setTo: 4 over: 5];
	[f2 setTo: 7 over: 8];
	
	dataVal1 = f1;
	dataVal2 = f2;
	
	result = [ dataVal1 add: dataVal2];
	[result print];
	[result release];
	
	
	
	[f1 release];
	[f2 release];
	[c1 release];
	[c2 release];
    [pool drain];
    return 0;
}
 

TotalLuck

macrumors newbie
Jan 3, 2009
21
0
Moreno Vallley
thanks Mdeh

Thanks a ton. again i was about to ask for help and there you are posting.

After pulling my hair out i see what was perplexing me.

I was trying to use f.numerator instead of [ f numerator].

So if i understand it , the dot notation is used when you/program knows what to expect from the object that was passed in. The [ f numerator] is basically saying go get this item. ( i had tried [f getNumerator] )

i don't have a problem getting the program to compile using the following
Code:
from fraction .m
-(id) add: (id) f
{   //add fractions together
	
	// result stores the reult of the addition
	
	
		Fraction *result = [[Fraction alloc] init];
		double resultNum, resultDenom , fnum ;
	
	if ( f < 0)
	{
		
		fnum = -1 * [f numerator];
		resultNum = numerator * [f denominator ] - denominator * fnum ;
		resultDenom = denominator * [f denominator];
		[result setTo:resultNum over: resultDenom];
	}
	
	else 
	{
		
		resultNum = numerator * [f denominator ]  + (denominator * [ f numerator ]);
		resultDenom = denominator * [  f denominator ];
		[result setTo:resultNum over: resultDenom];
	}
	if (resultNum > resultDenom)
	{	
		[result reduce];
	
	}
	
	return result;
	
}

int main(int argc, char *argv[])
{
	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc]init];

	id  result, dataValue2, dataValue1;
	Fraction *f1 = [[Fraction alloc]init];
	Fraction *f2 = [[Fraction alloc]init];
	ComplexNumbers *c1 = [[ ComplexNumbers alloc] init];
	ComplexNumbers *c2 = [[ ComplexNumbers alloc] init];

	[f1 setTo:2 over:5];
	[f2 setTo:5 over:8];
	
	result = [ f1 add: f2];
	[result print];

but when i add
Code:
	dataValue1 = f1;
	dataValue2 = f2;
	
	result = [ dataValue1 add: dataValue2 ];
	[result print];
	[result release];
i get error
" - void value not ignored as it ought to be. "
what am i missing there?
 

mdeh

macrumors 6502
Original poster
Jan 3, 2009
345
2
I was trying to use f.numerator instead of [ f numerator].

There clearly is a difference. Perhaps one of the more erudite contributors could clear this up?


Code:
i get  error 
" - void value not ignored as it ought to be. "
what am i missing there?[/QUOTE]


I am not sure if this would make any difference, but are you releasing "result" before you use it again?
 

skochan

macrumors regular
Apr 1, 2006
150
0
California
Thanks a ton. again i was about to ask for help and there you are posting.

After pulling my hair out i see what was perplexing me.

I was trying to use f.numerator instead of [ f numerator].

So if i understand it , the dot notation is used when you/program knows what to expect from the object that was passed in.

That's right! The dot notation cannot be used directly on id variables (you'd have to typecast it first to the appropriate object type). I should have pointed that out in the text--and I'll get it into the next printing.

but when i add
Code:
	dataValue1 = f1;
	dataValue2 = f2;
	
	result = [ dataValue1 add: dataValue2 ];
	[result print];
	[result release];
i get error
" - void value not ignored as it ought to be. "
what am i missing there?

Without seeing all the code, I'm guessing you have the add: method declared to return void somewhere (perhaps in the ComplexNumbers.h/.m files?). Let me know, or email the complete code to me.

Cheers,


Steve Kochan
 

TotalLuck

macrumors newbie
Jan 3, 2009
21
0
Moreno Vallley
Thanks again steve.

Here are the files
Code:
#import <Foundation/Foundation.h>
#import <objc/Object.h>

@interface Fraction	: NSObject
{
	int numerator;
	int denominator;
}

@property int numerator, denominator;

-(void) print;
-(double) convertToNum;
-(void) setTo: (int) n over: (int) d;
-(id) add:(id) f;
-(Fraction *) subtract: (Fraction *) f;
-(Fraction *) multiply: (Fraction *) f;
-(Fraction *) divide: (Fraction *)f;
-(void) reduce;


@end

Code:
#import "Fraction.h"


@implementation Fraction
@synthesize numerator, denominator;

-(void) print
{
	int whole, num2;
	BOOL needToReduce;
	
	if  ( numerator >= denominator)
		needToReduce = YES;
	
	
	if (needToReduce == YES)
	{
		whole = numerator / denominator;
		num2 = numerator % denominator;
		if (numerator % denominator == 0)
			NSLog(@" %i ", whole);
		else	
			NSLog(@" %i %i/%i ", whole, num2, denominator);
	}
	else
		NSLog(@" %i/%i ",numerator, denominator);
}

-(double) convertToNum
{
	
	if ( denominator != 0 )
		return (double)  numerator / denominator;
	else 
		return 1;
}

-(void) setTo: (int) n over: (int) d
{
	numerator = n;
	denominator = d;
}


-(id) add: (id) f
{   //add fractions together
	
	// result stores the reult of the addition
	
	
		Fraction *result = [[Fraction alloc] init];
		double resultNum, resultDenom , fnum ;
	
	if ( f < 0)
	{
		
		fnum = -1 * [f numerator];
		resultNum = numerator * [f denominator ] - denominator * fnum ;
		resultDenom = denominator * [f denominator];
		[result setTo:resultNum over: resultDenom];
	}
	
	else 
	{
		
		resultNum = numerator * [f denominator ]  + (denominator * [ f numerator ]);
		resultDenom = denominator * [  f denominator ];
		[result setTo:resultNum over: resultDenom];
	}
	if (resultNum > resultDenom)
	{	
		[result reduce];
	
	}
	
	return result;
	
}
	
-(Fraction *) subtract: (Fraction *) f
{
	//subtract fractions
	Fraction *result = [[Fraction alloc] init];
	int resultNum1, resultNum2, resultDenom, resultNum;
	
	
	if ( f < 0)
	{
		f.numerator = -1 * f.numerator;
		
		resultNum1 =(numerator * f.denominator) ;
		resultNum2 = (denominator * f.numerator);
		resultDenom = (denominator * f.denominator);
		
		resultNum = resultNum1 + resultNum2;
		
		[result setTo:resultNum		over: resultDenom];
	}
	
	else {
		
		resultNum1 =(numerator * f.denominator) ;
		resultNum2 = (denominator * f.numerator);
		resultDenom = (denominator * f.denominator);
		
		resultNum = resultNum1 - resultNum2;
		
		[result setTo:resultNum		over: resultDenom];
	}
	
	if (resultNum > resultDenom)
	{	
		[result reduce];
	}
	
	
	return result;
}
-(Fraction *) multiply: (Fraction *) f
{
	Fraction *result = [[Fraction alloc]init];
	int resultNum, resultDenom;
	
	
	if ( f < 0)
	{
		f.numerator = -1 * f.numerator;
		
		resultNum = numerator * f.numerator;
		resultDenom = denominator * f.denominator;
		
		[result setTo:resultNum over: resultDenom];
	}
	else 
	{
		
		resultNum = numerator * f.numerator;
		resultDenom = denominator * f.denominator;
		
		[result setTo:resultNum over: resultDenom];
	}
	
	if (resultNum > resultDenom)
	{	
		result.reduce;
	}
	
	return result;
}


-(Fraction *) divide: (Fraction *)f
{
	Fraction *result = [[Fraction alloc]init];
	int resultNum, resultDenom;
	
	resultNum = numerator * f.denominator;
	resultDenom = denominator * f.numerator;
	
	[result setTo:resultNum over: resultDenom];
	
	if (resultNum > resultDenom)
	{	
		result.reduce;
	}
	
	
	return result;
}



-(void) reduce
{
	int u = numerator;

	int v = denominator;
	int temp;
	
	
	
	while ( v != 0)
	{
		temp = u % v;
		u = v;
		v = temp;
	}
	
	numerator /= u;
	denominator /= u;
	
}


@end

Code:
#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>


@interface ComplexNumbers : NSObject
{
	double	real;
	double	imaginary;
}

@property double real, imaginary;

// methods 
-(void) setReal : (double) a andImaginary: (double) b;
-(void) print; // to print as  a + b(i)
-(id) add: (id)  c;




@end
Code:
#import "Complex.h"


@implementation ComplexNumbers

@synthesize real, imaginary;
// define methods
-(id) add: (id) c
{
	id result = [[ComplexNumbers alloc] init];
	double r1, imag1;
	
	r1		= real + [c real];
	imag1	= imaginary + [c imaginary];
	[result setReal:r1 andImaginary:imag1];
	
	return result;
	
}
-(void) setReal: (double) a  andImaginary: (double) b
{
	real = a , imaginary = b;
}

-(void) print  //  print the equation
{
	NSLog(@"(%g + %gi)", real, imaginary);
}

@end
Code:
#import <Foundation/Foundation.h>
#import "Fraction.h"
#import "Complex.h"


int main(int argc, char *argv[])
{
	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc]init];

	id  result, dataValue2, dataValue1;
	Fraction *f1 = [[Fraction alloc]init];
	Fraction *f2 = [[Fraction alloc]init];
	ComplexNumbers *c1 = [[ ComplexNumbers alloc] init];
	ComplexNumbers *c2 = [[ ComplexNumbers alloc] init];

	[f1 setTo:2 over:5];
	[f2 setTo:5 over:8];
	
	result = [ f1 add: f2];
	[result print];
	
	dataValue1 = f1;
	dataValue2 = f2;
	result = [ dataValue1 add: dataValue2 ];

	[result print];

	
	[c1 setReal: 10 andImaginary: 2.5 ];
	[c2 setReal: 14 andImaginary: 3];
	
	result = [ c1 add: c2 ];
	[result print];
	
	dataValue1 = c1;
	dataValue2 = c2;
	
	result = [ dataValue1 add: dataValue2 ];
	
	[result print];
	[result release];
	
	[c1 release];
	[c2 release];
	[f2 release];
	[f1 release];
	[pool drain];
	return 0;
	
	
}

i am using Xcode leopard 10.5

here is the debug
Code:
/users/lori/Desktop/Objectve c lessons/Rectangle/main.m: In function 'main':
/Users/lori/Desktop/Objectve c lessons/Rectangle/main.m:32: warning: multiple methods named '-add:' found
/Developer/SDKs/MacOSX10.5.sdk/System/Library/Frameworks/AppKit.framework/Headers/NSObjectController.h:59: warning: using '-(void)add:(id)sender'
/Users/lori/Desktop/Objectve c lessons/Rectangle/Fraction.h:22: warning: also found '-(id)add:(id)f'
/Users/lori/Desktop/Objectve c lessons/Rectangle/main.m:32: error: void value not ignored as it ought to be
/Users/lori/Desktop/Objectve c lessons/Rectangle/main.m:46: warning: multiple methods named '-add:' found
/[B]Developer/SDKs/MacOSX10.5.sdk/System/Library/Frameworks/AppKit.framework/Headers/NSObjectController.h:59: warning: using '-(void)add:(id)sender'[/B]
/Users/lori/Desktop/Objectve c lessons/Rectangle/Fraction.h:22: warning: also found '-(id)add:(id)f'
/Users/lori/Desktop/Objectve c lessons/Rectangle/main.m:46: error: void value not ignored as it ought to be
does it look like an error in the framework file?
 

skochan

macrumors regular
Apr 1, 2006
150
0
California
/Developer/SDKs/MacOSX10.5.sdk/System/Library/Frameworks/AppKit.framework/Headers/NSObjectController.h:59: warning: using '-(void)add: (id)sender'
[/CODE]
does it look like an error in the framework file?


Looks like the NSObjectController class has an add: method that returns void; thus the conflict at compile time. Use different method names (like addX). This goes back to the point made in the text about sending a message to an id type: all methods of the same name must agree in arguments and return type. This is actually a good learning exercise :D

By the way, you shouldn't be importing <objC/Object.h> . I don't have my book handy, but if that's from the text, it's a holdover from the first edition.

-----------
From Apple's documentation on the NSObjectController class:

add:
Creates a new object and sets it as the receiver’s content object.

- (void)add: (id)sender

Parameters
sender
Typically the object that invoked this method.
....

-------------

Cheers,

Steve Kochan
 

TotalLuck

macrumors newbie
Jan 3, 2009
21
0
Moreno Vallley
Thank you Steve

By the way, you shouldn't be importing <objC/Object.h> . I don't have my book handy, but if that's from the text, it's a holdover from the first edition.

Yeah i forgot to delete that.. I worked through the first 5 chapters in Book 1 then got Book 2 and forgot to change some of the file #imports. so dont chase down the editor just yet.

and thanks for the help. changing to the -(id)addX fixed the problem.
 

mdeh

macrumors 6502
Original poster
Jan 3, 2009
345
2
That's right! The dot notation cannot be used directly on id variables (you'd have to typecast it first to the appropriate object type). I should have pointed that out in the text--and I'll get it into the next printing.

Steve, I thought the "typecast" operator was () as in:

return (float) 7 /* where 7 is an int */

Here we use [ ..... ]. Could you elaborate a little.

Thank you.
 

skochan

macrumors regular
Apr 1, 2006
150
0
California
Steve, I thought the "typecast" operator was () as in:

return (float) 7 /* where 7 is an int */

Here we use [ ..... ]. Could you elaborate a little.

Thank you.

Ahh, I was hoping you wouldn't ask me that. If you knew the id object f was a Fraction, you could write the following:

Code:
((Fraction *) f).numerator

I'm only showing you this because you asked. But it's ugly!

Cheers,

Steve Kochan
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.