Inconsistent intemediate values in double (egcs bug?) 
Author Message
 Inconsistent intemediate values in double (egcs bug?)

While putting together some code to test just how much range I have
for whole numbers in floating point variables of different sizes on
different platforms, I encountered this.

My first surprise was the difference between #2 and #3.  The only
difference there is that the result of "x + 1.0" is stored in "y"
in #3 but not in #2.  Yet it results in an increased intermediate
precision.

My second surprise, more of a shock, was between #2 and #4, where
the very same code produced diferent results, depending on placement
in the program.

Is this a broken compiler?  A broken architecture?  Or am I just not
using C correctly?  My tendency would be to say the compiler is broken.
But I wanted to be sure I could rule the other possible causes out,
first.

--<SNIP HERE>----<SNIP HERE>----<SNIP HERE>----<SNIP HERE>----<SNIP HERE>--

#include <stdio.h>
int main() {
    double x,y;

    x = 1.0; while ( ( y = x + 1.0 ), y > x ) x = x + x;
    printf( "%66.1f\n" );

    x = 1.0; while ( (x + 1.0) > x ) x = x + x;
    printf( "%66.1f\n" );

    x = 1.0; while ( (y = x + 1.0) > x ) x = x + x;
    printf( "%66.1f\n" );

    x = 1.0; while ( (x + 1.0) > x ) x = x + x;
    printf( "%66.1f\n" );

    return 0;

Quote:
}



                                                9007199254740992.0
                                                9007199254740992.0
                                            18446744073709551616.0
                                            18446744073709551616.0

Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/specs
gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)

--<SNIP HERE>----<SNIP HERE>----<SNIP HERE>----<SNIP HERE>----<SNIP HERE>--

--
Phil Howard           KA9WGN



Wed, 13 Mar 2002 03:00:00 GMT  
 Inconsistent intemediate values in double (egcs bug?)


...

Quote:
>Is this a broken compiler?  A broken architecture?

Broken code.

Quote:
> Or am I just not
>using C correctly?  My tendency would be to say the compiler is broken.
>But I wanted to be sure I could rule the other possible causes out,
>first.

>--<SNIP HERE>----<SNIP HERE>----<SNIP HERE>----<SNIP HERE>----<SNIP HERE>--

>#include <stdio.h>
>int main() {
>    double x,y;

>    x = 1.0; while ( ( y = x + 1.0 ), y > x ) x = x + x;
>    printf( "%66.1f\n" );

>    x = 1.0; while ( (x + 1.0) > x ) x = x + x;
>    printf( "%66.1f\n" );

>    x = 1.0; while ( (y = x + 1.0) > x ) x = x + x;
>    printf( "%66.1f\n" );

>    x = 1.0; while ( (x + 1.0) > x ) x = x + x;
>    printf( "%66.1f\n" );

>    return 0;
>}


Always turn the warning level up on your compiler. With gcc at the
very least use gcc -Wall. Then your problem should be obvious.

--
-----------------------------------------


-----------------------------------------



Wed, 13 Mar 2002 03:00:00 GMT  
 Inconsistent intemediate values in double (egcs bug?)
Ah, the wonders of shuffling programs between machines and reformatting
bigger ones for simpler examples (didn't really want to post 300 lines).

However, it's still giving me the incorrect intermediate precision.
Is it valid to do the intermediate calculations with greater precision
than all the specified parts?




| ...

| >Is this a broken compiler?  A broken architecture?

| Broken code.

| > Or am I just not
| >using C correctly?  My tendency would be to say the compiler is broken.
| >But I wanted to be sure I could rule the other possible causes out,
| >first.
| >
| >--<SNIP HERE>----<SNIP HERE>----<SNIP HERE>----<SNIP HERE>----<SNIP HERE>--

| >#include <stdio.h>
| >int main() {
| >    double x,y;
| >
| >    x = 1.0; while ( ( y = x + 1.0 ), y > x ) x = x + x;
| >    printf( "%66.1f\n" );
| >
| >    x = 1.0; while ( (x + 1.0) > x ) x = x + x;
| >    printf( "%66.1f\n" );
| >
| >    x = 1.0; while ( (y = x + 1.0) > x ) x = x + x;
| >    printf( "%66.1f\n" );
| >
| >    x = 1.0; while ( (x + 1.0) > x ) x = x + x;
| >    printf( "%66.1f\n" );
| >
| >    return 0;
| >}

| Always turn the warning level up on your compiler. With gcc at the
| very least use gcc -Wall. Then your problem should be obvious.

| --
| -----------------------------------------


| -----------------------------------------

--
Phil Howard           KA9WGN



Thu, 14 Mar 2002 03:00:00 GMT  
 Inconsistent intemediate values in double (egcs bug?)

Quote:

> While putting together some code to test just how much range I have
> for whole numbers in floating point variables of different sizes on
> different platforms, I encountered this.

> My first surprise was the difference between #2 and #3.  The only
> difference there is that the result of "x + 1.0" is stored in "y"
> in #3 but not in #2.  Yet it results in an increased intermediate
> precision.

> My second surprise, more of a shock, was between #2 and #4, where
> the very same code produced diferent results, depending on placement
> in the program.

> Is this a broken compiler?  A broken architecture?  Or am I just not
> using C correctly?  My tendency would be to say the compiler is broken.
> But I wanted to be sure I could rule the other possible causes out,
> first.

It is a broken program.  Try using "-W -Wall -ansi -pedantic".  Then you
would at least know that you left out an argument in everyone of the
Quote:
>     printf( "%66.1f\n" );

statements.

--

__________________________________________________________
Fight spam now!
Get your free anti-spam service: http://www.brightmail.com



Thu, 14 Mar 2002 03:00:00 GMT  
 Inconsistent intemediate values in double (egcs bug?)
I think the problem is that you are confusing C/C++ with functional
languages.  'operator()' doesn't necessarily return the value of its
contents.  My guess is that your first to 'while' loops are producing
"correct" results.

Mark M. Young

 --<SNIP HERE>----<SNIP HERE>----<SNIP HERE>----<SNIP HERE>----

Quote:

> #include <stdio.h>
> int main() {
>     double x,y;

>     x = 1.0; while ( ( y = x + 1.0 ), y > x ) x = x + x;
>     printf( "%66.1f\n" );

>     x = 1.0; while ( (x + 1.0) > x ) x = x + x;
>     printf( "%66.1f\n" );

>     x = 1.0; while ( (y = x + 1.0) > x ) x = x + x;
>     printf( "%66.1f\n" );

>     x = 1.0; while ( (x + 1.0) > x ) x = x + x;
>     printf( "%66.1f\n" );

>     return 0;
> }


>                                                 9007199254740992.0
>                                                 9007199254740992.0
>                                             18446744073709551616.0
>                                             18446744073709551616.0

> Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/specs
> gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)

> --<SNIP HERE>----<SNIP HERE>----<SNIP HERE>----<SNIP HERE>----



Fri, 15 Mar 2002 03:00:00 GMT  
 Inconsistent intemediate values in double (egcs bug?)


Quote:
> Ah, the wonders of shuffling programs between machines and reformatting
> bigger ones for simpler examples (didn't really want to post 300 lines).
> However, it's still giving me the incorrect intermediate precision.
> Is it valid to do the intermediate calculations with greater precision
> than all the specified parts?

[...meaningless full quote deleted...]

Are you really too lazy to include a corrected code snippet.

        double x,y;

        for (x=1;x+1>x    ;x+=x); printf("%f\n",x);
        for (x=1;y=x+1,y>x;x+=x); printf("%f\n",x);

may produce wildly different results.

The C Standard says

...The values of operands and of results of expressions may be
represented in greater precision and range than that required by the
type...

Regards
Horst



Fri, 15 Mar 2002 03:00:00 GMT  
 Inconsistent intemediate values in double (egcs bug?)

| and yes, its fine to do the maths at higher precision. The precision
| of a float is only something like 6 sig figs so its easy to lose
| accuracy fast.

           Would it be also OK to do the math of double at the precision of
long double?  Would it even be OK to do the math at a precision
higher than can be represented in any type available to the
compiler?

--
Phil Howard           KA9WGN



Fri, 15 Mar 2002 03:00:00 GMT  
 Inconsistent intemediate values in double (egcs bug?)


| > However, it's still giving me the incorrect intermediate precision.
| > Is it valid to do the intermediate calculations with greater precision
| > than all the specified parts?

| The C Standard says
|
| ...The values of operands and of results of expressions may be
| represented in greater precision and range than that required by the
| type...

I guess this is what I'm running into, then.  The word "may" can mean
that it doesn't have to be consistent, either.

--
Phil Howard           KA9WGN



Fri, 15 Mar 2002 03:00:00 GMT  
 Inconsistent intemediate values in double (egcs bug?)
 > > Would it even be OK to do the math at a precision
 > > higher than can be represented in any type available to the
 > > compiler?
 > AFAICT, there is nothing in the C Standard that prevents this from
 > happening.  However, I suspect you might get a few irate customers if it
 > took several hours to do what should only take a couple seconds.

But that is not necessarily the case.  When I cross-compile on a Sun for
an Intel platform I would not be surprised when the object used 80-bit fp,
which is not available on the Sun.  And indeed, the standard allows this.
--
dik t. winter, cwi, kruislaan 413, 1098 sj  amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn  amsterdam, nederland; http://www.cwi.nl/~dik/



Sat, 16 Mar 2002 03:00:00 GMT  
 Inconsistent intemediate values in double (egcs bug?)


Quote:



> | > However, it's still giving me the incorrect intermediate precision.
> | > Is it valid to do the intermediate calculations with greater precision
> | > than all the specified parts?

> | The C Standard says
> |
> | ...The values of operands and of results of expressions may be
> | represented in greater precision and range than that required by the
> | type...

> I guess this is what I'm running into, then.  The word "may" can mean
> that it doesn't have to be consistent, either.

Well. This is an open question.

But - even assuming consistency - there is a problem which is not
clear to me. Maybe a language lawyer might answer.

If the implementation takes the licence to represent intermediate
results in some internal type - let's call it INTERNAL - wider than
double, and the comparison result of

           x+1 > x

evaluates to

        (INTERNAL)x + 1 > (INTERNAL)x

is it correct that even

        double x,y;

        (y=x+1) > x

yields the result of

        (INTERNAL)x + 1 > (INTERNAL)x

?  (gcc and Borland C++).

According to the Standard the value of the assignment expression is
the value of y _after_ the assignment. Can it be different from the
result of

        (y=x+1,y>x)

?

Regards
Horst



Sat, 16 Mar 2002 03:00:00 GMT  
 Inconsistent intemediate values in double (egcs bug?)


...

Quote:





>> | > However, it's still giving me the incorrect intermediate precision.
>> | > Is it valid to do the intermediate calculations with greater precision
>> | > than all the specified parts?

>> | The C Standard says
>> |
>> | ...The values of operands and of results of expressions may be
>> | represented in greater precision and range than that required by the
>> | type...

>> I guess this is what I'm running into, then.  The word "may" can mean
>> that it doesn't have to be consistent, either.
>Well. This is an open question.

>But - even assuming consistency - there is a problem which is not
>clear to me. Maybe a language lawyer might answer.

>If the implementation takes the licence to represent intermediate
>results in some internal type - let's call it INTERNAL - wider than
>double, and the comparison result of

>           x+1 > x

>evaluates to

>        (INTERNAL)x + 1 > (INTERNAL)x

>is it correct that even

>        double x,y;

>        (y=x+1) > x

>yields the result of

>        (INTERNAL)x + 1 > (INTERNAL)x

The standard requires the result of (INTERNAL)x + 1 to be reduced to the
precision of the type of y i.e. double so, no, this is not correct.

Quote:
>?  (gcc and Borland C++).

However many compilers get this wrong, often deliberately. Many compilers
have options to enforce stricter adherence to the floating point
rules (e.g. gcc's -ffloat-store) but even then they don't always
implement this perfectly.

Quote:
>According to the Standard the value of the assignment expression is
>the value of y _after_ the assignment. Can it be different from the
>result of

>        (y=x+1,y>x)

From the point of view of precision considerations, no. In practice
it might end up with the same result due to the compiler getting this
wrong in the same way.

--
-----------------------------------------


-----------------------------------------



Sat, 16 Mar 2002 03:00:00 GMT  
 
 [ 12 post ] 

 Relevant Pages 

1. inconsistent range of double in ISO/IEC 9899:1999

2. inconsistent return values from clock()

3. feof return value inconsistent

4. GetTextMetrics inconsistent values

5. addition long values to long double value ?

6. BUG? inconsistent wizard behavior when overloading operators

7. result of double*double is no double

8. Sorting on double values.

9. question about huge double value

10. Largest double value ...

11. Convert a string to a double value ?

12. value of : (double) clock( ) / CLOCKS_PER_SEC

 

 
Powered by phpBB® Forum Software