Related articles |
---|
Division in C++ garms@gmx.de (Onno Garms) (2005-07-11) |
Re: Division in C++ antounk@comcast.net (Antoun Kanawati) (2005-07-12) |
Re: Division in C++ qrczak@knm.org.pl (Marcin 'Qrczak' Kowalczyk) (2005-07-12) |
Re: Division in C++ tmk@netvision.net.il (Michael Tiomkin) (2005-07-12) |
Re: Division in C++ henry@spsystems.net (2005-07-12) |
Re: Division in C++ fw@deneb.enyo.de (Florian Weimer) (2005-07-12) |
Re: Division in C++ gdr@integrable-solutions.net (Gabriel Dos Reis) (2005-07-12) |
Re: Division in C++ qrczak@knm.org.pl (Marcin 'Qrczak' Kowalczyk) (2005-07-12) |
Re: Division in C++ garms@gmx.de (Onno Garms) (2005-07-17) |
Re: Division in C++ poenitz@htwm.de (Andre Poenitz) (2005-08-10) |
From: | henry@spsystems.net (Henry Spencer) |
Newsgroups: | comp.compilers,gnu.g++.help |
Date: | 12 Jul 2005 05:15:09 -0400 |
Organization: | SP Systems, Toronto, Canada |
References: | 05-07-046 |
Keywords: | arithmetic, C++ |
Posted-Date: | 12 Jul 2005 05:15:09 EDT |
In article 05-07-046, Onno Garms <garms@gmx.de> wrote:
>What I want the program to do in the loop is the following:
>1. compute a/b
>2. compute a/b again
>3. compare to previous result
>4. see that it is the same and break the loop
>However the program runs in an endless loop.
Almost certainly, what is happening here is that `a/b' is being
computed in extended precision -- normally a good thing to do, and
actually somewhat hard to avoid in the x86 floating-point architecture
-- and is being rounded to `double' when you assign it to the
variable. So no, the computed value of `a/b' is *not* quite the same
as the value assigned to the variable, so it is not surprising that
you get an infinite loop. When you do the comparison, the variable
value is being converted back to extended precision and compared to
the extended-precision result of the division, rather than the
extended-precision result being rounded to the precision of the
variable and then compared.
Try declaring `c' as `long double' instead. That might (depending on
the compiler) get you an extended-precision variable.
Floating-point computation unfortunately is full of subtleties like this.
Doing equality comparisons on floating-point values is almost never a
good idea.
>Regardless of any rounding errors, a/b should always return
>the same value, shouldn't it?
Yes... until it gets rounded to a lower precision to store it in a
variable.
>- Finally, the program below prints "not yet" (and nothing else):
> while (1)
> {
> c = a/b;
> if ((d=a/b)<=c) break;
> std::cout << "not yet\n";
> if (d<=c) break;
> std::cout << "but now\n";
> }
Now *this* is arguably a compiler bug. I would guess that in the first
comparison, the compiler is storing the value in `d' -- rounding it to
`double' in the process -- but is then using the old extended-precision
value still in the register for the comparison. That's possibly faster
than reloading the value from the variable, but it's not really right:
the value of the parenthesized subexpression is supposed to be the value
of the variable.
--
"Think outside the box -- the box isn't our friend." | Henry Spencer
-- George Herbert | henry@spsystems.net
Return to the
comp.compilers page.
Search the
comp.compilers archives again.