public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: "Chuck Allison" <cda@freshsources.com>
To: <cygwin@cygwin.com>
Subject: Strange behavior
Date: Sat, 02 Mar 2002 13:18:00 -0000	[thread overview]
Message-ID: <003501c1c22f$cd7c9570$0300000a@FSHPXP> (raw)

[-- Attachment #1: Type: text/plain, Size: 477 bytes --]

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@freshsources.com


[-- Attachment #2: Rational2.h --]
[-- Type: text/plain, Size: 2721 bytes --]

#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


[-- Attachment #3: Rational2.cpp --]
[-- Type: text/plain, Size: 1464 bytes --]

#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;
}



[-- Attachment #4: rtest2.cpp --]
[-- Type: text/plain, Size: 508 bytes --]

#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
*/



[-- Attachment #5: Type: text/plain, Size: 214 bytes --]

--
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/

             reply	other threads:[~2002-03-02 21:18 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-03-02 13:18 Chuck Allison [this message]
2002-03-02 15:09 ` David Means
2002-03-03 18:05 Ross Smith
2002-03-03 18:32 ` Randall R Schulz
2002-03-03 20:49   ` Richard R. Malloy
2002-03-03 21:08     ` Chuck Allison
2002-03-03 21:26 Robert Collins
2002-03-03 21:42 Gareth Pearce

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='003501c1c22f$cd7c9570$0300000a@FSHPXP' \
    --to=cda@freshsources.com \
    --cc=cygwin@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).