我一直在编写Steve Kochan的Objective-C 2.0编程书。如果有人拿到这本书的话,我可以参加第7章第4章的练习。
这个练习提出的问题是Fraction类的写作工作是负分数,如-1/2 + -2/3?
以下是相关的实施代码 -
@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;
}
-(Fraction *) add: (Fraction *) f
{
// To add two fractions:
// a/b + c/d = ((a * d) + (b * c)) / (b * d)
// result will store the result of the addition
Fraction *result = [[Fraction alloc] init];
int resultNum, resultDenom;
resultNum = (numerator * f.denominator) + (denominator * f.numerator);
resultDenom = denominator * f.denominator;
[result setTo: resultNum over: resultDenom];
[result reduce];
return result;
}
-(Fraction *) subtract: (Fraction *) f
{
// To subtract two fractions:
// a/b - c/d = ((a * d) - (b * c)) / (b * d)
// result will store the result of the addition
Fraction *result = [[Fraction alloc] init];
int resultNum, resultDenom;
resultNum = numerator * f.denominator - denominator * f.numerator;
resultDenom = denominator * f.denominator;
[result setTo: resultNum over: resultDenom];
[result reduce];
return result;
}
-(Fraction *) multiply: (Fraction *) f
{
// To multiply two fractions
// a/b * c/d = (a*c) / (b*d)
// result will store the result of the addition
Fraction *result = [[Fraction alloc] init];
int resultNum, resultDenom;
resultNum = numerator * f.numerator;
resultDenom = denominator * f.denominator;
[result setTo: resultNum over: resultDenom];
[result reduce];
return result;
}
-(Fraction *) divide: (Fraction *) f
{
// To divide two fractions
// a/b / c/d = (a*d) / (b*c)
// result will store the result of the addition
Fraction *result = [[Fraction alloc] init];
int resultNum, resultDenom;
resultNum = numerator * f.denominator;
resultDenom = denominator * f.numerator;
[result setTo: resultNum over: 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
我向你提出的问题是,它是否适用于负分数,你能解释一下你的知识吗?部分问题是我不知道如何自己计算负分数,所以我不太清楚如何知道。
非常感谢。
答案 0 :(得分:2)
代码中的注释给出了公式。由于您不了解它们,因此您认为评论是正确的是合理的。
从普通常识来看,你也可以推断负分数的行为不依赖于它们的符号。
例如,如果您知道负数一般如何工作(例如考虑温度),则没有理由让分数表现不同(例如,温度为160/3就可以了)。毕竟,一小部分只是一个数字。
现在从我快速查看代码,我没有看到任何情况下这个代码与其数据的符号愚弄。例如,它永远不会取任何东西的绝对值。所以我的结论是它应该与负分数一起使用就好了。
现在,如果你可以选择实际运行代码,你可以在几个测试用例中检查它。
话虽如此,这段代码有一件事无法处理:在数学上,负分数是分子或分母为负(但不是两者)的分数。惯例是优先选择分子上的减号。该守则不会尊重或执行该惯例。
但是,这并没有使代码错误。然而,这为未来扩张留下了陷阱。例如,假设您展开该类以比较两个分数是否相等。以下天真的实现是错误的:- (BOOL) isEqualTo:(Fraction*)f
{
[self reduce];
[f reduce];
BOOL b = (self.numerator == f.numerator) && (self.denominator == f.denominator);
return b;
}
这样的实现会错误地声称(-2)/ 3不等于2 /( - 3)。
我留给你想象一个更好的实现。