【问题标题】:Calculating negative fractions in Objective C在 Objective C 中计算负分数
【发布时间】:2010-03-20 23:06:14
【问题描述】:

我一直在通过 Steve Kochan 的 Objective-C 2.0 编程一书编写自己的代码。我准备在第 7 章前 4 中做一个练习,以防万一有人有这本书。

练习提出的问题是分数类书面作业是否会处理负分数,例如 -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

我的问题是它是否适用于负分数?你能解释一下你是怎么知道的吗?部分问题是我自己不知道如何计算负分数,所以我不太确定如何知道。

非常感谢。

【问题讨论】:

    标签: objective-c math fractions


    【解决方案1】:

    代码中的 cmets 给出了公式。由于您不了解它们,因此您有理由相信 cmets 是正确的。

    根据普通常识,您还可以推断出负分数的行为不取决于它们的符号。

    例如,如果您知道负数的一般工作原理(例如考虑温度),那么分数就没有理由表现不同(例如,可以说温度是 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)。

    我留给你想象一个更好的实现。

    【讨论】:

    • 仅供参考:编辑问题以将 self.reduce; 等更改为 [self reduce];。使用点语法调用不是属性的 getter 或 setter 的方法违背了他们的意图,永远不应该使用。
    • 感谢您的回复并帮助我理解这一点。
    猜你喜欢
    • 2013-09-04
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-22
    • 1970-01-01
    相关资源
    最近更新 更多