🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.help
Article #51714

Re: Floating point differences

#51714
From: Hugh Fader
Date: Fri, 16 Apr 1993 16:02
114 lines
5346 bytes
I wrote:
: We have an application here that does a lot of floating point
: calculations. We have noticed differences in results between gcc and
: other compilers. i.e. cc on Sun, Borland C on PC, and MS C on PC give
: identical results. Only gcc on Sun differs. Does gcc do something

I think I know the problem. It has to do with differences in the
treatment of floats in traditional and ANSI C.

The definition of traditional C, `The C Programming Language' by
Kernighan and Ritchie (1978) p. 41, states:

    More precisely, for each arithmetic operator, the following
    sequence of conversion rules is applied.

    	char and short are converted to int, and float is converted to
    	double.

    . . .

ANSI C may treat floats differently. In `The C Programming Language
Second Edition' by Kernighan and Ritchie (1988) p. 198 states:

    . . . arithmetic on float may be done in single precision, rather
    than double; the first edition specified that all floating
    arithmetic was double precision.

I think that *may* is the operative word in the above quotation. I
know that cc is doing double arithmetic. You will see that both the
Borland and Microsoft compilers are promoting to double while the GNU
compiler is not.

A reply to my posting (included at the end of this message) included a
program for calculating the computer's epsilon, the smallest value
significantly different from zero. The program calculates epsilon two
ways, once with an intermediate variable and once without. The
intermediate variable forces truncation to float precision. The
calculation without the intermediate variable depends on compiler
implementation to determine whether float or double is used.

Here is the epsilon output run on Sun with three different
compiler/switch combinations:

    slee06% cc -o epsilon epsilon.c
    slee06% epsilon
    Epsilon machine (avec variable intermediaire) : 1.19209e-07
    Epsilon machine (sans variable intermediaire) : 2.22045e-16

    slee06% gcc -o epsilon epsilon.c
    slee06% epsilon
    Epsilon machine (avec variable intermediaire) : 1.19209e-07
    Epsilon machine (sans variable intermediaire) : 1.19209e-07

    slee06% gcc -traditional -o epsilon epsilon.c
    slee06% epsilon
    Epsilon machine (avec variable intermediaire) : 1.19209e-07
    Epsilon machine (sans variable intermediaire) : 2.22045e-16

The epsilon values from gcc's float.h are:

    #define FLT_EPSILON ((float)1.19209290e-07)
    #define DBL_EPSILON 2.2204460492503131e-16

As expected, cc appears to be doing double precision arithmetic. The
intermediate variable is truncating to float. The first run of gcc has
identical results with or without the intermediate variable. This
indicates it is not promoting float to double for arithmetic
operations. The second run of gcc, with the -traditional compiler
flag, gives the same result as for cc. Even though the gcc manual page
gives no indication of this, -traditional must be causing gcc to treat
float arithmetic the same way as cc does.

The Microsoft compiler gave the following results for epsilon:

    Epsilon machine (avec variable intermediaire) : 1.0842e-019
    Epsilon machine (sans variable intermediaire) : 1.0842e-019

The epsilon values from float.h are:
    #define DBL_EPSILON	2.2204460492503131e-016
    #define FLT_EPSILON	1.192092896e-07F
    #define LDBL_EPSILON	5.4210108624275221706e-020

The epsilon program's output value is smaller than that given for
DBL_EPSILON in float.h!  It appears that through optimization (maybe
by keeping floats in fpa registers) the Microsoft compiler avoids the
truncation by the intermediate variable.

The Borland compiler gave

    Epsilon machine (avec variable intermediaire) : 1.19209e-07
    Epsilon machine (sans variable intermediaire) : 1.0842e-19

Its epsilon values from float.h are:

    #define DBL_EPSILON         2.2204460492503131E-16
    #define FLT_EPSILON         1.19209290E-07F
    #define LDBL_EPSILON        1.084202172485504E-19

The Borland compiler behaves similarly to cc execept that it gives
a value for the double epsilon is the LDBL value.

Summing things up, it looks like everybody but gcc is promoting floats
to double.

We tried compiling our application with gcc -traditional and the
results matched those of cc.

Does anyone have suggestions as to what the best approach is when you
want consistent floating point results from several compilers? One
way to do this would be to only use doubles. This is OK except when
you have large data sets.


----------- begin included file ------------------
Technical Details
Message-ID: <1qmla6INNb25@fmsrl7.srl.ford.com>
Path: arc1-ca.pugleaf.net!gmd.de!newsserver.jvnc.net!louie!udel!gatech!emory!nigel.msen.com!fmsrl7!hugh
References: <1qhbioINN55a@fmsrl7.srl.ford.com>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 11318c,e3259ca760e1e814
X-Google-Attributes: gid11318c,public
X-Google-ArrivalTime: 1993-04-16 09:24:31 PST
Path: arc1-ca.pugleaf.net!gmd.de!newsserver.jvnc.net!louie!udel!gatech!emory!nigel.msen.com!fmsrl7!hugh
From: hugh@slee01.srl.ford.com (Hugh Fader)
Newsgroups: gnu.gcc.help
Subject: Re: Floating point differences
Date: 16 Apr 1993 16:02:08 GMT
Organization: Ford Motor Company Research Laboratory
Lines: 205
Message-ID: <1qmla6INNb25@fmsrl7.srl.ford.com>
References: <1qhbioINN55a@fmsrl7.srl.ford.com>
Reply-To: hugh@slee01.srl.ford.com
NNTP-Posting-Host: slee06.srl.ford.com
X-Newsreader: Tin 1.1 PL5