www.ShoppingPodder.com

Leading Computer Shopping,
News and information


Part of the Identityscape.com network...

getxfactor.com jmoodmusic.com smartbusinesschoices.com mintdepot.com lowfaresalways.com evangelicalview.com shoppingpodder.com soproudlywehail.com webnews.ws currenthumor.com

 

 

Floating point bug? Or Feature?
   Shopping Podder - the Best of Computer Postings! Forum Index -> Computer Architecture - Arithmetic  
View previous topic :: View next topic  
Author Message
Tim Mensch
Guest






PostPosted: Sat Mar 08, 2008 6:59 am    Post subject: Floating point bug? Or Feature? Reply with quote

Can someone tell me why this isn't a bug?

double foo = INT_MAX ;
double bar = 0 ;
double bax = foo + bar ;

ASSERT(foo==INT_MAX); // This succeeds; easily enough precision to hold 2^31
ASSERT(bax==INT_MAX); // This fails!? INT_MAX+0 == INT_MAX+1!?

I built this on Visual C++ 2005 with /fp=precision ("precision" floating point). It created very simple floating point assembly language (this is from a debug build, but it fails in debug and release):

double foo = INT_MAX ;
00513C21 fld qword ptr [__real@41dfffffffc00000 (576208h)]
00513C27 fstp qword ptr [ebp-48h]
double bar = 0 ;
00513C2A fldz
00513C2C fstp qword ptr [ebp-58h]
double bax = foo + bar ;
00513C2F fld qword ptr [ebp-48h]
00513C32 fadd qword ptr [ebp-58h]
00513C35 fstp qword ptr [ebp-68h]

Sure enough, when the fadd is executed, the stack floating point value goes from INT_MAX to INT_MAX+1, even though it's adding a zero. This happens on both an Intel Pentium Core2Duo and an AMD Turion64 (running in 32-bit mode).

Please CC my email address when replying, or it may take me a while to notice. Yes, it's a real address as-is, at least for now--if it ends up blocked in the future, or I don't reply to it, then change the number and it will work again. Smile

Thanks in advance!

Tim Mensch
Back to top
glen herrmannsfeldt
Guest






PostPosted: Mon Mar 10, 2008 2:35 am    Post subject: Re: Floating point bug? Or Feature? Reply with quote

Tim Mensch wrote:

Quote:
Can someone tell me why this isn't a bug?

double foo = INT_MAX ;
double bar = 0 ;
double bax = foo + bar ;

ASSERT(foo==INT_MAX); // This succeeds; easily enough precision to hold 2^31
ASSERT(bax==INT_MAX); // This fails!? INT_MAX+0 == INT_MAX+1!?

Does it depend on the rounding mode?

Can you store the temporary real (80 bit) internal values and show
the hex value of them?

-- glen


Quote:
I built this on Visual C++ 2005 with /fp=precision ("precision" floating point). It created very simple floating point assembly language (this is from a debug build, but it fails in debug and release):

double foo = INT_MAX ;
00513C21 fld qword ptr [__real@41dfffffffc00000 (576208h)]
00513C27 fstp qword ptr [ebp-48h]
double bar = 0 ;
00513C2A fldz
00513C2C fstp qword ptr [ebp-58h]
double bax = foo + bar ;
00513C2F fld qword ptr [ebp-48h]
00513C32 fadd qword ptr [ebp-58h]
00513C35 fstp qword ptr [ebp-68h]
Back to top
Quadibloc
Guest






PostPosted: Wed Mar 12, 2008 7:35 pm    Post subject: Re: Floating point bug? Or Feature? Reply with quote

On Mar 7, 6:59 pm, "Tim Mensch" <tim-usenet-4...@bitgems.com> wrote:
Quote:
Can someone tell me why this isn't a bug?

      double foo = INT_MAX ;
      double bar = 0 ;
      double bax = foo + bar ;

      ASSERT(foo==INT_MAX);  // This succeeds; easily enough precision to hold 2^31
      ASSERT(bax==INT_MAX); // This fails!?  INT_MAX+0 == INT_MAX+1!?

That is definitely unexpected behavior on most computing systems.

Unlike decimal fractions, integers are represented exactly in floating-
point, and integers are typically 32 bits long while double-precision
floating-point occupies 64 bits and typically uses 8 or 9 bits for the
exponent.

Even if INT_MAX turned out to be 2^63-1 because your system used 64-
bit integers, so that the floats involved were not exact, adding zero
ought not to have produced a result differing from the original
number, so both assertions should have either succeeded or failed
together.
Back to top
purnnamu
Guest






PostPosted: Sat Mar 15, 2008 2:00 am    Post subject: Re: Floating point bug? Or Feature? Reply with quote

On Mar 7, 7:59 pm, "Tim Mensch" <tim-usenet-4...@bitgems.com> wrote:
Quote:
Can someone tell me why this isn't a bug?

      double foo = INT_MAX ;
      double bar = 0 ;
      double bax = foo + bar ;

      ASSERT(foo==INT_MAX);  // This succeeds; easily enough precision to hold 2^31
      ASSERT(bax==INT_MAX); // This fails!?  INT_MAX+0 == INT_MAX+1!?

I built this on Visual C++ 2005 with /fp=precision ("precision" floating point). It created very simple floating point assembly language (this is from a debug build, but it fails in debug and release):

      double foo = INT_MAX ;
00513C21  fld         qword ptr [__real@41dfffffffc00000 (576208h)]
00513C27  fstp        qword ptr [ebp-48h]
      double bar = 0 ;
00513C2A  fldz
00513C2C  fstp        qword ptr [ebp-58h]
      double bax = foo + bar ;
00513C2F  fld         qword ptr [ebp-48h]
00513C32  fadd        qword ptr [ebp-58h]
00513C35  fstp        qword ptr [ebp-68h]

Sure enough, when the fadd is executed, the stack floating point value goes from INT_MAX to INT_MAX+1, even though it's adding a zero. This happens on both an Intel Pentium Core2Duo and an AMD Turion64 (running in 32-bit mode)..

Please CC my email address when replying, or it may take me a while to notice. Yes, it's a real address as-is, at least for now--if it ends up blocked in the future, or I don't reply to it, then change the number and it will work again. :)

Thanks in advance!

Tim Mensch


I tested the code in my environments (Intel Core2 duo, VC++ 6.0 and
gcc3.xx 32-bit).
It works correctly in both environments.

In some compiler environment, FPU processes all calculations in 80-
bit.
And then, the outputs are converted into 64-bit format using FST
instruction.
I have experienced a problem that the output is different from
IEEE-754 due to this 80-bit internal operation.
(in my case, gcc 3.xx 32-bit)

However, your code works correctly in the gcc 3.xx 32-bit environment.
I checked.

I don't know why you got the bizarre result in your environment.
I also agree that your code should work as you expected.

Inwook

----------- the tested code -----------

#include "limits.h"
#include "assert.h"

int main(void)
{
double foo= INT_MAX;
double bar= 0;
double bax=foo+bar;

if(foo==INT_MAX)printf("foo=INT_MAX\n");
if(bax==INT_MAX)printf("bax=INT_MAX\n");

assert(foo==INT_MAX);
assert(bax==INT_MAX);
}
Back to top
purnnamu
Guest






PostPosted: Sat Mar 15, 2008 2:08 am    Post subject: Re: Floating point bug? Or Feature? Reply with quote

On Mar 7, 7:59 pm, "Tim Mensch" <tim-usenet-4...@bitgems.com> wrote:
Quote:
Can someone tell me why this isn't a bug?

double foo = INT_MAX ;
double bar = 0 ;
double bax = foo + bar ;

ASSERT(foo==INT_MAX); // This succeeds; easily enough precision to hold 2^31
ASSERT(bax==INT_MAX); // This fails!? INT_MAX+0 == INT_MAX+1!?

I built this on Visual C++ 2005 with /fp=precision ("precision" floating point). It created very simple floating point assembly language (this is from a debug build, but it fails in debug and release):

double foo = INT_MAX ;
00513C21 fld qword ptr [__real@41dfffffffc00000 (576208h)]
00513C27 fstp qword ptr [ebp-48h]
double bar = 0 ;
00513C2A fldz
00513C2C fstp qword ptr [ebp-58h]
double bax = foo + bar ;
00513C2F fld qword ptr [ebp-48h]
00513C32 fadd qword ptr [ebp-58h]
00513C35 fstp qword ptr [ebp-68h]

Sure enough, when the fadd is executed, the stack floating point value goes from INT_MAX to INT_MAX+1, even though it's adding a zero. This happens on both an Intel Pentium Core2Duo and an AMD Turion64 (running in 32-bit mode).

Please CC my email address when replying, or it may take me a while to notice. Yes, it's a real address as-is, at least for now--if it ends up blocked in the future, or I don't reply to it, then change the number and it will work again. :)

Thanks in advance!

Tim Mensch



I tested the code in my environments (Intel Core2 duo, VC++ 6.0 and
gcc3.xx 32-bit).
It works correctly in both environments.

In some compiler environment, FPU processes all calculations in 80-
bit.
And then, the outputs are converted into 64-bit format using FST
instruction.
I have experienced a problem that the output is different from
IEEE-754 due to this 80-bit internal operation.
(in my case, gcc 3.xx 32-bit)


However, your code works correctly in the gcc 3.xx 32-bit
environment.

I don't know why you got the bizarre result in your environment.
I also agree that your code should work as you expected.


Inwook


----------- the tested code -----------


#include "limits.h"
#include "assert.h"


void main(void)
{
double foo= INT_MAX;
double bar= 0;
double bax=foo+bar;


if(foo==INT_MAX)printf("foo=INT_MAX\n");
if(bax==INT_MAX)printf("bax=INT_MAX\n");


assert(foo==INT_MAX);
assert(bax==INT_MAX);
}
Back to top
Tim Mensch
Guest






PostPosted: Sat Mar 15, 2008 10:06 am    Post subject: Re: Floating point bug? Or Feature? Reply with quote

First, thanks for all the replies. I didn't notice them at first; I need to get a more convenient news reader set up.

When I again attempted to reproduce the problem, it actually worked correctly this time. A bit more experimentation leads me to the conclusion that the error only happens after initializing a CppUnit class: CppUnit::TextTestRunner. Does anyone know of something it might be doing that would change the behavior of the FPU? (forcing it to use 32-bit floats internally, perhaps?) My assembly language skills don't extend to the arcana of current Intel FPU modes.

To answer a few questions:

1. When I was first debugging the problem, I was able to watch the floating point registers in the debugger, and I could see the floating point add cause the value in the debugger change from INT_MAX, to INT_MAX+1:

+2.1474836470000000e+0009 changed to
+2.1474836480000000e+0009

And to answer related a question about precision, the raw representation in hex of the 64-bit double is:

41dfffffffc00000 for INT_MAX
and
41e0000000000000 for INT_MAX+1, so clearly there's plenty of precision to spare.

2. I'm building with 32-bit integers.

3. I'm building on Visual Studio 2005.

4. I'm embarrassed to admit I don't know how to set the rounding mode. My code (that currently works) is using the compiler flag /fp:precise, though /fp:fast and /fp:strict both also work.

Thanks again,

Tim
Back to top
glen herrmannsfeldt
Guest






PostPosted: Mon Mar 17, 2008 1:19 am    Post subject: Re: Floating point bug? Or Feature? Reply with quote

Tim Mensch wrote:
(snip)

Quote:
4. I'm embarrassed to admit I don't know how to set the rounding mode. My code (that currently works) is using the compiler flag /fp:precise, though /fp:fast and /fp:strict both also work.

This was for another question, but it shows how to set precision
and rounding modes on some systems.

#include <stdio.h>
#include <assert.h>
#include <limits.h>
#include <floatingpoint.h>

int main() {
double foo = 1.0;
double bar = 0.9999999999999;
double bax;
int i,j;

fpsetround(FP_RP);
printf("%d\n",fpgetround());
for(i=0;i<4;i++) for(j=0;j<4;j++) {
fpsetround(i);
fpsetprec(j);
bax = foo - bar ;
printf("%20.14e %d %d\n",bax,fpgetround(),fpgetprec());
}
}

This is on my FreeBSD system, but other gcc systems
don't have them.

-- glen
Back to top
Nick Maclaren
Guest






PostPosted: Mon Mar 17, 2008 1:55 am    Post subject: Re: Floating point bug? Or Feature? Reply with quote

In article <6pWdnWqxbrIk4kDanZ2dnUVZ_qygnZ2d@comcast.com>,
glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
|> Tim Mensch wrote:
|>
|> > 4. I'm embarrassed to admit I don't know how to set the rounding mode. My code (that currently works) is using the compiler flag /fp:precise, though /fp:fast and /fp:strict both also work.
|>
|> This was for another question, but it shows how to set precision
|> and rounding modes on some systems.
|>
|> #include <stdio.h>
|> #include <assert.h>
|> #include <limits.h>
|> #include <floatingpoint.h>
|>
|> int main() {
|> double foo = 1.0;
|> double bar = 0.9999999999999;
|> double bax;
|> int i,j;
|>
|> fpsetround(FP_RP);
|> printf("%d\n",fpgetround());
|> for(i=0;i<4;i++) for(j=0;j<4;j++) {
|> fpsetround(i);
|> fpsetprec(j);
|> bax = foo - bar ;
|> printf("%20.14e %d %d\n",bax,fpgetround(),fpgetprec());
|> }
|> }

Which includes half a dozen serious errors, where C99 specifies very
explicitly undefined behaviour. That might do what you expect, or may
do something totally insane - even ignoring the Berzerkeleyisms of
<floatingpoint.h>, fpsetprec and fpgetprec. And don't expect any
help from the documentation or vendor.

Please correct me if I am wrong, but I don't believe that FreeBSD or
any other system documents the aspects where you have invoked undefined
behaviour - or, indeed, fpsetprec and fpgetprec. The 'specification'
that I can find simply says that they set and read the precision!

Sorry, but this minefield is a disaster even for experts.


Regards,
Nick Maclaren.
Back to top
glen herrmannsfeldt
Guest






PostPosted: Mon Mar 17, 2008 3:23 am    Post subject: Re: Floating point bug? Or Feature? Reply with quote

Nick Maclaren wrote:
(snip)

Quote:
|> for(i=0;i<4;i++) for(j=0;j<4;j++) {
|> fpsetround(i);
|> fpsetprec(j);
|> bax = foo - bar ;
|> printf("%20.14e %d %d\n",bax,fpgetround(),fpgetprec());
|> }
|> }

Which includes half a dozen serious errors, where C99 specifies very
explicitly undefined behaviour. That might do what you expect, or may
do something totally insane - even ignoring the Berzerkeleyisms of
floatingpoint.h>, fpsetprec and fpgetprec. And don't expect any
help from the documentation or vendor.

My gcc is 2.7.2.3 which is probably before C99. (The machine is
mostly used as a network router, currently has been up 386 days,
and that is not a record.)

Quote:
Please correct me if I am wrong, but I don't believe that FreeBSD or
any other system documents the aspects where you have invoked undefined
behaviour - or, indeed, fpsetprec and fpgetprec. The 'specification'
that I can find simply says that they set and read the precision!

No claims to the contrary. It was a quick test to see if FPU
rounding modes could cause surprising results. Among the
undefined behavior is that there are only three precision
values defined. The non-standard routines are likely valid
only for x87 systems. The arguments are supposed to be enums.
I forget if the standard sets requirements on enum values if
none are specified.

Quote:
Sorry, but this minefield is a disaster even for experts.

It did what I wanted it to do, but I do agree that there
are many non-standard features in use. The man page says
they are based on SysV/386 features.

-- glen
Back to top
Display posts from previous:   
   Shopping Podder - the Best of Computer Postings! Forum Index -> Computer Architecture - Arithmetic  
Page 1 of 1
All times are GMT

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum