C++ 分数类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5690663/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ Fractions Class
提问by Sahat Yalkabov
I have to create a class called Fractionswith 2 private fields Numerator, Denominator. And a public constructor that sets Numerator and Denominator to 1 by default. I have included 4 members functions in my my Fractionsclass: Sum, Difference, Product, Division.
我必须创建一个名为Fractions的类,其中包含 2 个私有字段Numerator, Denominator。以及一个公共构造函数,默认情况下将 Numerator 和 Denominator 设置为 1。我在我的Fractions类中包含了 4 个成员函数:Sum、Difference、Product、Division。
Then I am not sure what to do next. Why does book show fraction equivalences? What do I have to do with that? I guess a very important question would be what parameters should my member functions take?
然后我不确定下一步该怎么做。为什么 book 显示分数等价?我与那有什么关系?我想一个非常重要的问题是我的成员函数应该采用什么参数?
Also what would be a good way to prohibit denominator of 0? Throw exception or force it to be equal to 1?
还有什么是禁止分母为 0 的好方法?抛出异常还是强制它等于 1?
Here is the complete source code for the question #5 and #6 (not shown) after struggling with the problem for days.Questions #6 just asks to implement the greatest common divisor function to return fraction in a simplified form. So here it is...
这是问题 #5 和 #6(未显示)的完整源代码,经过数天的努力。问题 #6 只是要求实现最大公约数函数以简化形式返回分数。所以这里是...
If you think there is a way to optimize this code I'd be happy to hear your responses!
如果您认为有一种方法可以优化此代码,我很高兴听到您的回复!
#include <iostream>
using namespace std;
class Fraction
{
private:
int numerator, denominator;
public:
Fraction()
{
numerator = 1;
denominator = 1;
}
Fraction(int n, int d)
{
numerator = n;
if (d==0)
{
cout << "ERROR: ATTEMPTING TO DIVIDE BY ZERO" << endl;
exit(0); // will terminate the program if division by 0 is attempted
}
else
denominator = d;
}
/*In the following functions I am dividing both numerator and denominator by the gcd function.
GCD function accepts both numerator and denominator values. If we had 2 fractions, 1/2 and 1/4
and we passed it into the Sum, the result would be n=6 and d=8. These are the values that GCD
function will accept, find greatest common divisor and return the integer value of 2. In my case
am diving both numerator and denominator on the same line by the greatest common divisor. Although
it probably would be more efficient to create a local int variable and store GCD value in it, but
for such small program it shouldn't make any difference.*/
Fraction Sum(Fraction otherFraction)
{
int n = numerator*otherFraction.denominator+otherFraction.numerator*denominator;
int d = denominator*otherFraction.denominator;
return Fraction(n/gcd(n,d),d/gcd(n,d));
}
Fraction Difference(Fraction otherFraction)
{
int n = numerator*otherFraction.denominator-otherFraction.numerator*denominator;
int d = denominator*otherFraction.denominator;
return Fraction(n/gcd(n,d),d/gcd(n,d));
}
Fraction Product(Fraction otherFraction)
{
int n = numerator*otherFraction.numerator;
int d = denominator*otherFraction.denominator;
return Fraction(n/gcd(n,d),d/gcd(n,d));
}
Fraction Division(Fraction otherFraction)
{
int n = numerator*otherFraction.denominator;
int d = denominator*otherFraction.numerator;
return Fraction(n/gcd(n,d),d/gcd(n,d));
}
// I got the GCD algorithm from the following source:
// Source C#: http://www.ww.functionx.com/csharp2/examples/gcd.htm
int gcd(int n, int d)
{
int remainder;
while (d != 0)
{
remainder = n % d;
n = d;
d = remainder;
}
return n;
}
void show() // Display method
{
if (denominator == 1) // e.g. fraction 2/1 will display simply as 2
cout << numerator << endl;
else
cout << numerator << "/" << denominator << endl;
}
};
int main()
{
Fraction a(1,2);
Fraction b(1,4);
Fraction c;
c = a.Sum(b); // Result: 3/4
c.show();
c = a.Difference(b); // Result: 1/4
c.show();
c = a.Product(b); // Result: 1/8
c.show();
c = a.Division(b); // Result: 2
c.show();
return 0;
}
采纳答案by James Black
You may want to start with just the first part, create the class with two constructors, one if they give the two numbers, and one that defaults to 1
.
您可能只想从第一部分开始,创建具有两个构造函数的类,一个如果给出两个数字,一个默认为1
.
Then, write the four functions, the assignment is nice enough to give you the equations.
然后,写出这四个函数,赋值已经足够给你方程式了。
If a denominator is ever equal to zero then I would throw an exception, as that is something the user may be able to fix. If you can show what led to it being zero, for example, if they divide (1/2)/(0/4) then your denominator is zero, which should be an error condition.
如果分母永远等于零,那么我会抛出异常,因为这是用户可能能够修复的问题。如果您可以显示导致它为零的原因,例如,如果它们除以 (1/2)/(0/4),那么您的分母为零,这应该是错误条件。
One issue you will want to look at is if this will be immutable, so, if I have (1/2) and (2/3) and I do an operation, it should return a new number, not modify either of the two that I passed in. In that case your check is always in the constructor for a zero, but you should explain which operation led to this error.
您要查看的一个问题是这是否是不可变的,因此,如果我有 (1/2) 和 (2/3) 并且我执行了一个操作,它应该返回一个新数字,而不是修改两者中的任何一个我传入的。在那种情况下,你的检查总是在构造函数中为零,但你应该解释哪个操作导致了这个错误。
回答by david van brink
Also what would be a good way to prohibit denominator of 0? Throw exception or force it to be equal to 1?
还有什么是禁止分母为 0 的好方法?抛出异常还是强制它等于 1?
That's completely a style question, with no provably correct answer...
这完全是一个风格问题,没有可证明的正确答案......
But... I'd go with an exception. Again, this is just style. Changing the value silently would be carrying on silently forward having done something other than what the caller asked for.
但是......我会去一个例外。同样,这只是风格。静默更改该值将在完成调用者要求的操作之外的其他操作后静默进行。
Another alternative would be to allow 0 denominator, but have a way to inform the user that the current overall value, a/b, is NaN or infinity, or whatever "special value" you care to define.
另一种选择是允许分母为 0,但有一种方法可以通知用户当前的总体值 a/b 是 NaN 或无穷大,或者您想定义的任何“特殊值”。
In any case, document it carefully, so a user of the class can make informed choices.
无论如何,请仔细记录它,以便类的用户可以做出明智的选择。
回答by David Titarenco
Your fraction constructor should take a numerator and a denominator as parameters (or a whole number). The entire problem could be solved easily with operator overloading.
您的分数构造函数应将分子和分母作为参数(或整数)。整个问题可以通过运算符重载轻松解决。
And yes, the best way to handle failed constructors is via exceptions. Don't forget to throw the same division_by_zero
exception when you're dividing two fractions and the numerator of the denominator is zero.
是的,处理失败的构造函数的最佳方法是通过 exceptions。division_by_zero
当您将两个分数相除并且分母的分子为零时,不要忘记抛出相同的异常。
回答by Brian Roach
Your methods could be (assuming your class is named "Fraction"):
你的方法可能是(假设你的类被命名为“分数”):
Fraction Fraction::sum(Fraction &otherFraction)
Fraction Fraction::difference(Fraction &otherFraction)
Fraction Fraction::product(Fraction &otherFraction)
Fraction Fraction::division(Fraction &otherFraction)
(Using the method names you described - I might go for something different)
(使用您描述的方法名称-我可能会采用不同的方法)
Each of these would return a new Fraction
object containing the result.
每一个都将返回一个Fraction
包含结果的新对象。
You'd be into bonus points for using operator overloading and re-defining what + - / *
meant.
您会因使用运算符重载和重新定义+ - / *
含义而获得加分。
回答by Johnsyweb
So many questions in one question! Let me answer one (pair) for you:
一题这么多题!让我为您解答一个(对):
Why does book show fraction equivalences? What do I have to do with that?
为什么 book 显示分数等价?我与那有什么关系?
Consider this usage of your Fraction
class:
考虑您的Fraction
类的这种用法:
TEST(FractionsAreEquivalent)
{
const Fraction one_over_two(1, 2); // 0.5
const Fraction two_over_four(2, 4); // 0.5
const bool equivalent = (one_over_two == two_over_four);
CHECK(equivalent);
}
This uses bool Fraction::operator ==(const Fraction& rhs) const
.
这使用bool Fraction::operator ==(const Fraction& rhs) const
.