delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2002/03/02/16:18:43

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
Message-ID: <003501c1c22f$cd7c9570$0300000a@FSHPXP>
From: "Chuck Allison" <cda AT freshsources DOT com>
To: <cygwin AT cygwin DOT com>
Subject: Strange behavior
Date: Sat, 2 Mar 2002 14:18:30 -0700
MIME-Version: 1.0
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 6.00.2600.0000
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000

------=_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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019