* RE: Strange behavior
@ 2002-03-03 21:42 Gareth Pearce
0 siblings, 0 replies; 8+ messages in thread
From: Gareth Pearce @ 2002-03-03 21:42 UTC (permalink / raw)
To: cygwin
>Floating point comparisons should _always_ be done via a confidence
>interval, not bitwise equality. As for determinism, I don't know what
>the logic circuits look like, so can't and won't comment :}.
>
>Rob
confidence intervals are indeed the only way...
but as to determinism ... its a function of your compiler I believe.
Differences will likely arrise with or without optimisation.
Which coincidently - is also the difference between the 2 situations below,
1 is an optimisation of the other, the assembly produced, even without an
optimisation flag, will be different, which means different results (one
case needs temporary variables - other one does not). So it should be
deterministic for a single set of assembly, for a given system type...
although someone could easily of made a processor in which I am wrong.
Gareth
>
>
>
> > -----Original Message-----
> > From: Chuck Allison [mailto:cda@freshsources.com]
> > Sent: Monday, March 04, 2002 4:08 PM
> > To: Richard R. Malloy; Randall R Schulz
> > Cc: Ross Smith; cygwin@cygwin.com
> > Subject: Re: Strange behavior
> >
> >
> > That's the point. They're always redued, so in both cases,
> > the expression 2.0/3.0 is evaluated. How can that be
> > non-deterministic?
> >
> > ----- Original Message -----
> > From: "Richard R. Malloy" <rrmalloy@attbi.com>
> > To: "Randall R Schulz" <rrschulz@cris.com>
> > Cc: "Ross Smith" <rosss@pharos.co.nz>; "'Chuck Allison'"
> > <cda@freshsources.com>; <cygwin@cygwin.com>
> > Sent: Sunday, March 03, 2002 9:47 PM
> > Subject: Re: Strange behavior
> >
> >
> > > OK. I'm no IA32 expert can someone explain the following
> > results. (Do
> > > the floating point registers use guard bits, randomly initialized
> > > perhaps?)
> > >
> > > bool operator==(const Rational& r1, const Rational& r2)
> > > {
> > > double a=r1.toDouble(), b=r2.toDouble();
> > > cout << ?== a " << a << " " << ?== b " << b << endl;
> > > return a == b;
> > > // return r1.toDouble() == r2.toDouble();
> > > /* return ( r1.numerator == r2.numerator && r1.denominator ==
> > > r2.denominator ); */ }
>
>--
>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/
>
_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp.
--
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/
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: Strange behavior
@ 2002-03-03 21:26 Robert Collins
0 siblings, 0 replies; 8+ messages in thread
From: Robert Collins @ 2002-03-03 21:26 UTC (permalink / raw)
To: Chuck Allison, Richard R. Malloy, Randall R Schulz; +Cc: Ross Smith, cygwin
Floating point comparisons should _always_ be done via a confidence
interval, not bitwise equality. As for determinism, I don't know what
the logic circuits look like, so can't and won't comment :}.
Rob
> -----Original Message-----
> From: Chuck Allison [mailto:cda@freshsources.com]
> Sent: Monday, March 04, 2002 4:08 PM
> To: Richard R. Malloy; Randall R Schulz
> Cc: Ross Smith; cygwin@cygwin.com
> Subject: Re: Strange behavior
>
>
> That's the point. They're always redued, so in both cases,
> the expression 2.0/3.0 is evaluated. How can that be
> non-deterministic?
>
> ----- Original Message -----
> From: "Richard R. Malloy" <rrmalloy@attbi.com>
> To: "Randall R Schulz" <rrschulz@cris.com>
> Cc: "Ross Smith" <rosss@pharos.co.nz>; "'Chuck Allison'"
> <cda@freshsources.com>; <cygwin@cygwin.com>
> Sent: Sunday, March 03, 2002 9:47 PM
> Subject: Re: Strange behavior
>
>
> > OK. I'm no IA32 expert can someone explain the following
> results. (Do
> > the floating point registers use guard bits, randomly initialized
> > perhaps?)
> >
> > bool operator==(const Rational& r1, const Rational& r2)
> > {
> > double a=r1.toDouble(), b=r2.toDouble();
> > cout << ?== a " << a << " " << ?== b " << b << endl;
> > return a == b;
> > // return r1.toDouble() == r2.toDouble();
> > /* return ( r1.numerator == r2.numerator && r1.denominator ==
> > r2.denominator ); */ }
--
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/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Strange behavior
2002-03-03 20:49 ` Richard R. Malloy
@ 2002-03-03 21:08 ` Chuck Allison
0 siblings, 0 replies; 8+ messages in thread
From: Chuck Allison @ 2002-03-03 21:08 UTC (permalink / raw)
To: Richard R. Malloy, Randall R Schulz; +Cc: Ross Smith, cygwin
That's the point. They're always redued, so in both cases, the expression
2.0/3.0 is evaluated. How can that be non-deterministic?
----- Original Message -----
From: "Richard R. Malloy" <rrmalloy@attbi.com>
To: "Randall R Schulz" <rrschulz@cris.com>
Cc: "Ross Smith" <rosss@pharos.co.nz>; "'Chuck Allison'"
<cda@freshsources.com>; <cygwin@cygwin.com>
Sent: Sunday, March 03, 2002 9:47 PM
Subject: Re: Strange behavior
> OK. I'm no IA32 expert can someone explain the following results. (Do
> the floating point registers
> use guard bits, randomly initialized perhaps?)
>
> bool operator==(const Rational& r1, const Rational& r2)
> {
> double a=r1.toDouble(), b=r2.toDouble();
> cout << ?== a " << a << " " << ?== b " << b << endl;
> return a == b;
> // return r1.toDouble() == r2.toDouble();
> /* return ( r1.numerator == r2.numerator && r1.denominator ==
> r2.denominator ); */
> }
>
> 5/4
> == a 1.25 == b 1.25
> 1
> -1/4
> == a -0.25 == b -0.25
> 1
> 3/8
> == a 0.375 == b 0.375
> 1
> 2/3
> == a 0.666667 == b 0.666667
> 0 // return
> r1.toDouble() == r2.toDouble();
>
> 5/4
> == a 1.25 == b 1.25
> 1
> -1/4
> == a -0.25 == b -0.25
> 1
> 3/8
> == a 0.375 == b 0.375
> 1
> 2/3
> == a 0.666667 == b 0.666667
> 1 return a == b;
>
>
> But since the Rational are always reduced the "right" answer is
>
> return ( r1.numerator == r2.numerator && r1.denominator ==
> r2.denominator );
>
> No?
>
> Rich.
>
> Randall R Schulz wrote:
>
> > Ross,
> >
> > To call that result "pure luck" denies the fact that digital
> > computers, when properly functioning, are 100% deterministic.
> >
> > Of course, it's not proper floating-point programming, but that
> > doesn't mean "luck" is involved.
> >
> > Randall Schulz
> > Mountain View, CA USA
> >
> >
> > At 18:04 2002-03-03, Ross Smith wrote:
> >
> >> > From: Chuck Allison [mailto:cda@freshsources.com]
> >> >
> >> > 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.
> >>
> >> [relevant bit of code]
> >>
> >> inline bool operator==(const Rational& r1, const Rational& r2)
> >> {
> >> return r1.toDouble() == r2.toDouble();
> >> }
> >>
> >> This is nothing to do with Cygwin, or g++ for that matter. You're
> >> comparing floating point numbers. Of course it's not reliable! If
> >> other compilers happened to give you an exact equality on that
> >> particular combination of arguments, it was pure luck.
> >
> >
> >
> > --
> > 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/
> >
> >
>
>
>
--
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/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Strange behavior
2002-03-03 18:32 ` Randall R Schulz
@ 2002-03-03 20:49 ` Richard R. Malloy
2002-03-03 21:08 ` Chuck Allison
0 siblings, 1 reply; 8+ messages in thread
From: Richard R. Malloy @ 2002-03-03 20:49 UTC (permalink / raw)
To: Randall R Schulz; +Cc: Ross Smith, 'Chuck Allison', cygwin
OK. I'm no IA32 expert can someone explain the following results. (Do
the floating point registers
use guard bits, randomly initialized perhaps?)
bool operator==(const Rational& r1, const Rational& r2)
{
double a=r1.toDouble(), b=r2.toDouble();
cout << ?== a " << a << " " << ?== b " << b << endl;
return a == b;
// return r1.toDouble() == r2.toDouble();
/* return ( r1.numerator == r2.numerator && r1.denominator ==
r2.denominator ); */
}
5/4
== a 1.25 == b 1.25
1
-1/4
== a -0.25 == b -0.25
1
3/8
== a 0.375 == b 0.375
1
2/3
== a 0.666667 == b 0.666667
0 // return
r1.toDouble() == r2.toDouble();
5/4
== a 1.25 == b 1.25
1
-1/4
== a -0.25 == b -0.25
1
3/8
== a 0.375 == b 0.375
1
2/3
== a 0.666667 == b 0.666667
1 return a == b;
But since the Rational are always reduced the "right" answer is
return ( r1.numerator == r2.numerator && r1.denominator ==
r2.denominator );
No?
Rich.
Randall R Schulz wrote:
> Ross,
>
> To call that result "pure luck" denies the fact that digital
> computers, when properly functioning, are 100% deterministic.
>
> Of course, it's not proper floating-point programming, but that
> doesn't mean "luck" is involved.
>
> Randall Schulz
> Mountain View, CA USA
>
>
> At 18:04 2002-03-03, Ross Smith wrote:
>
>> > From: Chuck Allison [mailto:cda@freshsources.com]
>> >
>> > 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.
>>
>> [relevant bit of code]
>>
>> inline bool operator==(const Rational& r1, const Rational& r2)
>> {
>> return r1.toDouble() == r2.toDouble();
>> }
>>
>> This is nothing to do with Cygwin, or g++ for that matter. You're
>> comparing floating point numbers. Of course it's not reliable! If
>> other compilers happened to give you an exact equality on that
>> particular combination of arguments, it was pure luck.
>
>
>
> --
> 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/
>
>
--
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/
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: Strange behavior
2002-03-03 18:05 Ross Smith
@ 2002-03-03 18:32 ` Randall R Schulz
2002-03-03 20:49 ` Richard R. Malloy
0 siblings, 1 reply; 8+ messages in thread
From: Randall R Schulz @ 2002-03-03 18:32 UTC (permalink / raw)
To: Ross Smith, 'Chuck Allison', cygwin
Ross,
To call that result "pure luck" denies the fact that digital computers,
when properly functioning, are 100% deterministic.
Of course, it's not proper floating-point programming, but that doesn't
mean "luck" is involved.
Randall Schulz
Mountain View, CA USA
At 18:04 2002-03-03, Ross Smith wrote:
> > From: Chuck Allison [mailto:cda@freshsources.com]
> >
> > 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.
>
>[relevant bit of code]
>
>inline bool operator==(const Rational& r1, const Rational& r2)
>{
> return r1.toDouble() == r2.toDouble();
>}
>
>This is nothing to do with Cygwin, or g++ for that matter. You're
>comparing floating point numbers. Of course it's not reliable! If other
>compilers happened to give you an exact equality on that particular
>combination of arguments, it was pure luck.
--
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/
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: Strange behavior
@ 2002-03-03 18:05 Ross Smith
2002-03-03 18:32 ` Randall R Schulz
0 siblings, 1 reply; 8+ messages in thread
From: Ross Smith @ 2002-03-03 18:05 UTC (permalink / raw)
To: 'Chuck Allison', cygwin
> From: Chuck Allison [mailto:cda@freshsources.com]
>
> 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.
[relevant bit of code]
inline bool operator==(const Rational& r1, const Rational& r2)
{
return r1.toDouble() == r2.toDouble();
}
This is nothing to do with Cygwin, or g++ for that matter. You're
comparing floating point numbers. Of course it's not reliable! If
other compilers happened to give you an exact equality on that
particular combination of arguments, it was pure luck.
--
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/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Strange behavior
2002-03-02 13:18 Chuck Allison
@ 2002-03-02 15:09 ` David Means
0 siblings, 0 replies; 8+ messages in thread
From: David Means @ 2002-03-02 15:09 UTC (permalink / raw)
To: cygwin
[-- Attachment #1: Type: text/plain, Size: 1109 bytes --]
I don't think it's cygwin.
Looks like something in gnu (complier or libs?).
David
---
72$ uname -a && g++ --version && ./rtest2
Linux milo 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown
2.96
5/4
1
-1/4
1
3/8
1
2/3
0
319$ uname -a && g++ --version ; ./rtest2
SunOS opus 5.7 Generic sun4u sparc SUNW,Ultra-1
2.95.3
5/4
1
-1/4
1
3/8
1
2/3
1
On Sat, 2002-03-02 at 16:18, Chuck Allison wrote:
> 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
>
> ----
>
{ snip }
--
No trees were killed in the sending of this message. However,
a large number of electrons were terribly inconvenienced.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 240 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Strange behavior
@ 2002-03-02 13:18 Chuck Allison
2002-03-02 15:09 ` David Means
0 siblings, 1 reply; 8+ messages in thread
From: Chuck Allison @ 2002-03-02 13:18 UTC (permalink / raw)
To: cygwin
[-- 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/
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2002-03-04 5:42 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-03-03 21:42 Strange behavior Gareth Pearce
-- strict thread matches above, loose matches on Subject: below --
2002-03-03 21:26 Robert Collins
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-02 13:18 Chuck Allison
2002-03-02 15:09 ` David Means
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).