1

私は、Steve Kochan の Programming in 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

あなたへの私の質問は、それが負の分数で機能するかどうか、そしてあなたがどのように知っているか説明できますか? 問題の一部は、負の分数を自分で計算する方法がわからないため、知る方法がよくわかりません。

どうもありがとう。

4

1 に答える 1

2

コード内のコメントは式を示しています。あなたはそれらを知らないので、コメントが正しいと信じるのが合理的です.

単純な常識から、負の分数の振る舞いはその符号に依存しないことも推測できます。

たとえば、負の数が一般的にどのように機能するかを知っている場合 (たとえば、温度を考えてください)、分数が異なる動作をする理由はありません (たとえば、温度が 160/3 であると言っても問題ありません)。結局のところ、分数は数にすぎません。

コードをざっと見てみると、このコードがデータの符号でだまされているケースは見当たりません。たとえば、何かの絶対値を取ることはありません。したがって、私の結論は、負の分数でも問題なく機能するはずです。

実際にコードを実行するオプションがある場合は、いくつかのテスト ケースで確認できます。

そうは言っても、このコードでは処理できないことが 1 つあります。数学的には、負の分数とは、分子または分母のいずれかが負である (ただし、両方ではない) ものです。規則では、分子のマイナス記号を優先します。そのコードは、その規則を尊重または強制しません。

ただし、コードが間違っているわけではありません。ただし、これは将来の拡張の罠になります。たとえば、そのクラスを拡張して、2 つの分数が等しいかどうかも比較するとします。次の素朴な実装は間違っています。

- (BOOL) isEqualTo:(Fraction*)f
{
  [self reduce];
  [f reduce];
  BOOL b = (self.numerator == f.numerator) && (self.denominator == f.denominator);
  return b;
}

このような実装は、(-2)/3 が 2/(-3) と等しくないと誤って主張します。

より良い実装を想像するのはあなたに任せます。

于 2010-03-20T23:24:59.247 に答える