Mail Archives: cygwin/2002/03/02/16:18:43
------=_NextPart_000_0032_01C1C1F5.20DB0F20
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
I have a simple Rational number class and have discovered weird behavior
with Cygwin's g++. If you look at the very short main program in file
rtest2.cpp, you will see by the output that g++ get's the wrong answer for
r1 / r2 == Rational(2,3); // should be true
even though it prints as 2/3! Borland and Microsoft get it right. Any ideas?
All code atached.
Thanks.
-- Chuck Allison (The Harmonious CodeSmith)
-- Senior Editor, C/C++ Users Journal
-- cda AT freshsources DOT com
------=_NextPart_000_0032_01C1C1F5.20DB0F20
Content-Type: text/plain;
name="Rational2.h"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="Rational2.h"
#ifndef RATIONAL_H
#define RATIONAL_H
#include <cassert>
#include <iosfwd>
using std::istream;
using std::ostream;
class Rational
{
int numerator;
int denominator;
void reduce();
double toDouble() const;
public:
Rational(int numerator = 0, int denominator = 1);
Rational operator-() const;
friend Rational operator+(const Rational&, const Rational&);
friend Rational operator-(const Rational&, const Rational&);
friend Rational operator*(const Rational&, const Rational&);
friend Rational operator/(const Rational&, const Rational&);
friend ostream& operator<<(ostream&, const Rational&);
// Extra credit stuff
Rational& operator+=(const Rational&);
Rational& operator-=(const Rational&);
Rational& operator*=(const Rational&);
Rational& operator/=(const Rational&);
friend istream& operator>>(istream&, Rational&);
friend bool operator<(const Rational&, const Rational&);
friend bool operator>(const Rational&, const Rational&);
friend bool operator<=(const Rational&, const Rational&);
friend bool operator>=(const Rational&, const Rational&);
friend bool operator==(const Rational&, const Rational&);
friend bool operator!=(const Rational&, const Rational&);
};
inline Rational::Rational(int numerator, int denominator)
{
this->numerator = numerator;
this->denominator = denominator;
assert(denominator != 0);
reduce();
}
inline Rational Rational::operator-() const
{
return Rational(-numerator, denominator);
}
inline Rational operator+(const Rational& r1, const Rational& r2)
{
Rational temp(r1);
return temp += r2;
}
inline Rational operator-(const Rational& r1, const Rational& r2)
{
Rational temp(r1);
return temp -= r2;
}
inline Rational operator*(const Rational& r1, const Rational& r2)
{
Rational temp(r1);
return temp *= r2;
}
inline Rational operator/(const Rational& r1, const Rational& r2)
{
Rational temp(r1);
return temp /= r2;
}
inline bool operator<(const Rational& r1, const Rational& r2)
{
return r1.toDouble() < r2.toDouble();
}
inline bool operator>(const Rational& r1, const Rational& r2)
{
return r1.toDouble() > r2.toDouble();
}
inline bool operator<=(const Rational& r1, const Rational& r2)
{
return r1.toDouble() <= r2.toDouble();
}
inline bool operator>=(const Rational& r1, const Rational& r2)
{
return r1.toDouble() >= r2.toDouble();
}
inline bool operator==(const Rational& r1, const Rational& r2)
{
return r1.toDouble() == r2.toDouble();
}
inline bool operator!=(const Rational& r1, const Rational& r2)
{
return !(r1.toDouble() == r2.toDouble());
}
inline double Rational::toDouble() const
{
return double(numerator)/denominator;
}
#endif
------=_NextPart_000_0032_01C1C1F5.20DB0F20
Content-Type: text/plain;
name="Rational2.cpp"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="Rational2.cpp"
#include "Rational2.h"
#include <iostream>
#include <cstdlib>
using namespace std;
// gcd functions: would normally be a static members
int gcd2(int x, int y)
{
return (y == 0) ? x : gcd2(y, x%y);
}
int gcd(int x, int y)
{
// Force result to be positive
return gcd2(abs(x), abs(y));
}
void Rational::reduce()
{
int div = gcd(numerator, denominator);
assert(div > 0);
if (div != 1)
{
numerator /= div;
denominator /= div;
}
}
Rational& Rational::operator+=(const Rational& r)
{
numerator = numerator*r.denominator + denominator*r.numerator;
denominator = denominator*r.denominator;
reduce();
return *this;
}
Rational& Rational::operator-=(const Rational& r)
{
numerator = numerator*r.denominator - denominator*r.numerator;
denominator = denominator*r.denominator;
reduce();
return *this;
}
Rational& Rational::operator*=(const Rational& r)
{
numerator *= r.numerator;
denominator *= r.denominator;
reduce();
return *this;
}
Rational& Rational::operator/=(const Rational& r)
{
assert(r.numerator != 0);
numerator *= r.denominator;
denominator *= r.numerator;
reduce();
return *this;
}
istream& operator>>(istream& is, Rational& r)
{
char slash;
is >> r.numerator >> slash;
assert(slash == '/');
is >> r.denominator;
r.reduce();
return is;
}
ostream& operator<<(ostream& os, const Rational& r)
{
return os << r.numerator << '/' << r.denominator;
}
------=_NextPart_000_0032_01C1C1F5.20DB0F20
Content-Type: text/plain;
name="rtest2.cpp"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="rtest2.cpp"
#include <iostream>
#include "Rational2.h"
using namespace std;
int main()
{
Rational r1(1,2), r2(3,4);
cout << r1 + r2 << endl;
cout << (r1 + r2 == Rational(5,4)) << endl;
cout << r1 - r2 << endl;
cout << (r1 - r2 == Rational(-1,4)) << endl;
cout << r1 * r2 << endl;
cout << (r1 * r2 == Rational(3,8)) << endl;
cout << r1 / r2 << endl;
cout << (r1 / r2 == Rational(2,3)) << endl;
}
/* Cygwin output:
5/4
1
-1/4
1
3/8
1
2/3
0
*/
/* Other compilers
5/4
1
-1/4
1
3/8
1
2/3
1
*/
------=_NextPart_000_0032_01C1C1F5.20DB0F20
Content-Type: text/plain; charset=us-ascii
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Bug reporting: http://cygwin.com/bugs.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
------=_NextPart_000_0032_01C1C1F5.20DB0F20--
- Raw text -