Update: The issue is clearly mathematical, if anyone has any input on how to add the wholeNumber into the calculation methods, any help would be appreciated.
I'm quite baffled here. I'm writing an objective c program and creating an object of fraction.
Within my fraction object I have methods to add, subtract, multiply, etc. Everything works pretty much as should but for some reason after I call my math methods, I'm loosing my whole number to be displayed. If I enter 5/4 for my fraction and call the print method I get 1 1/4, but when I call the add method and send another fraction object 5/4 (so I'm adding 5/4 + 5/4), store it into a result object and print and only get 1/2 when I should be getting 2 1/2. Am I overlooking something here, or storing something within my math functions wrong? I am newer to objective-c obviously. Why am I loosing the whole number in this output? It should be 2 1/2 instead I get just 1/2
Fraction *Fraction1 = [[Fraction alloc] init];// fraction object
Fraction *Fraction2 = [[Fraction alloc] init];// fraction object
Fraction *result;
[Fraction1 setTo: 5 over: 4];
[Fraction2 setTo: 5 over: 4];
[Fraction1 print];
[Fraction2 print];
result = [Fraction1 add: Fraction2];
//display the fraction
NSLog (@"the value of myFraction is: ");
[result print];
For my main.
#import "fraction.h"
@implementation Fraction
@synthesize numerator;
@synthesize denominator;
@synthesize wholeNumber;
-(Fraction *) add:(Fraction *)fraction{
Fraction *result =[[Fraction alloc] init];
result.numerator = (numerator * fraction.denominator) + (fraction.numerator * denominator);
result.denominator = denominator * fraction.denominator;
[result reduce];
return result;
}
-(Fraction *) divide:(Fraction *)fraction {
Fraction *result =[[Fraction alloc] init];
result.numerator = numerator * fraction.denominator;
result.denominator = denominator * fraction.numerator;
[result reduce];
return result;
}
-(Fraction *) multiply:(Fraction *)fraction{
Fraction *result =[[Fraction alloc] init];
result.numerator = numerator * fraction.numerator;
result.denominator = denominator * fraction.denominator;
[self reduce];
return result;
}
-(Fraction *) subtract:(Fraction *) fraction{
Fraction *result =[[Fraction alloc] init];
result.numerator = (numerator * fraction.denominator) - (fraction.numerator * denominator);
result.denominator = denominator * fraction.denominator;
[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;
}
-(void) print{
if (numerator > denominator && numerator % denominator == 0) {
int wholeNumber = numerator / denominator;
NSLog(@"The whole number is %i", wholeNumber);
} else if ( numerator > denominator) {
wholeNumber = numerator / denominator;
numerator = numerator % denominator;
NSLog(@"Mixed fraction %i %i/%i", wholeNumber, numerator, denominator);
} else {
NSLog(@"%i/%i", numerator, denominator);
}
}
-(void) setTo:(int) n over: (int) d {
numerator = n;
denominator = d;
}
-(int) numerator{
return numerator;
}
-(void) setNumerator: (int) n{
numerator = n;
}
-(void) setDenominator: (int) d{
denominator = d;
}
-(int) denominator{
return denominator;
}
-(double) convertToNum{
if (denominator !=0)
return (double) numerator/denominator;
else
return NAN;
}
-(int) wholeNum {
return wholeNumber;
}
-(void) setWholeNum: (int) n {
wholeNumber = n;
}
@end
fraction class
-(Fraction *) add:(Fraction *)fraction{
Fraction *result =[[Fraction alloc] init];
result.numerator = (numerator * fraction.denominator) + (fraction.numerator * denominator);
result.denominator = denominator * fraction.denominator;
[result reduce];
return result;
}
And finally my add method
Output below
Mixed fraction 1 1/4
Mixed fraction 1 1/4
the value of myFraction is:
1/2
Program ended with exit code: 0
'''
Your math methods do not take into account the wholenumber
value, only the numerator
and denominator
, so every time you do a math operation the wholenumber
value in the result
is 0
.
Your reduce
also ignores the wholenumber
value but it does at least preserve it (so 1 8/4 reduces to 1 2/1 rather than to 3).
When you call print
that is the only time you set wholenumber
, and any future operations will either zero the value (maths) or ignore it (reduce).
HTH
Addendum after comment
Is there a better way to represent these mathematically?
Representing a value as a fraction with the pair of integers numerator, denominator or as a mixed number with the triple of integers wholenumber, numerator, denominator does not effect the mathematical accuracy/result/etc.
However, unlike mathematics where the range of integers is unlimited, computers tend to do arithmetic with integers having a finite range – e.g. the type unsigned int
on a 64-bit architecture can only represent values in the range 0 to 9,223,372,036,854,775,807 (2^64 - 1) which while rather large is not unlimited.
One consequence of this is it is best to operate on fractions in irreducible form; i.e. never represent a 1/2 as 2,305,843,009,213,693,952/4,611,686,018,427,387,904; as this helps keep each integer within the limited range available.
Another consideration is whether to allow improper fractions, where the numerator is larger than the denominator pair, e.g. 4/3; or to use mixed numbers for these, e.g. 1 1/3. The latter can increase the range of values that can be represented, e.g. 1 1/9,223,372,036,854,775,807 cannot be represented as the improper fraction 9,223,372,036,854,775,808/9,223,372,036,854,775,807 using 64-but unsigned integers as the numerator is too large and would cause an overflow error.
So how to represent fractions depends on the goal:
If the fractions are likely to always have small values for numerator and denominator then you can allow improper and fractions and reduce the result after an operation; you'll probably avoid overflow etc.
If the goal is to provide general purpose fractions which avoid overflows where possible and provide the maximum range of representable values then you choose a mixed number representation and reduce during the operation.
If the goal is to allow improper and unreduced fractions and work for any values at all regardless of computational cost you can choose the first option combined with an arbitrary precision integer library/framework and avoid overflow and range issues that way – at least until your computer runs out of memory...
The Wikipedia page Fraction is a good start for the mathematics side of this, it doesn't cover the issues of limited computer arithmetic though.
(Note for simplicity the above examples used unsigned numbers as the basis of the range of integers, fractions of course can be negative so the normal signed integers would be used [though the denominator could be unsigned]).
If I try adding values like wholeNumber = denominator / numerator (to the add method) but it will only work mathematically 1/2 the time.
That simply means you've got error in your implementation, how you represent your values isn't the issue. If you are adding the mixed numbers a b/c
& d e/f
then, ignoring issues of improper and unreduced fractions, the sum is:
wholenumber = a + d
numerator = b * f + e * c
denominator = c * f
If you cannot get your implementation to work ask a new question explaining your representation, algorithm, where it goes wrong, what you've tried etc. and someone will undoubtedly help you out.