🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.bug
Article #5991

Floating point to long long conversions

#5991
From: Jeremiah W. James
Date: Fri, 20 Dec 1996 00:00
117 lines
4924 bytes
Greetings!

I have the following two configurations of GCC available to me:

                  MIPS II     SPARC V8
                  ----------  -----------
GCC version:      2.7.2.1     2.7.2
Machine name:     SGI Indy    Sun LX
Operating system: IRIX 5.3    Solaris 2.5
Processor:        MIPS R4600  Sparc V8
Uses GAS?         Yes         Yes
Uses GNU ld?      No          Yes
Binutils version: 2.7         2.6

Both configurations produce odd results when converting from a floating
point value too large to fit into the the target type.  The following
results were obtained on both configurations.  In both cases, the native
compiler produced the expected value.

Target type Example
----------- ---------------------------------------------------
long long    1e+25 => -1  (Expect LONGLONG_MAX)
long long   -1e+25 =>  1  (Expect LONGLONG_MIN)
long long    inf   => -1  (Expect LONGLONG_MAX)
long long   -inf   =>  1  (Expect LONGLONG_MIN)


On the MIPS II configuration only, conversions from values that are
close to the maximum size of the target type sometimes produce the wrong
results.  This is an intermittent bug.  I got the wrong results
consistently until I wrote the test program appended below.  Upon
running it, I received the correct results.  Puzzled, I reran my
original program, and found to my astonishment that it now produces the
correct results consistently.  I can only surmise that something in the
OS or hardware was in a funny state, and running the test program
somehow pushed it into the correct state.  I can provide the original
program on request.

At first, when I was receiving the incorrect result, it made no
difference if the original number was in a float or a double.  The
optimization level did not affect the results.  Setting or not setting
the -mips2 flag had no effect.  While receiving the incorrect results,
the same program compiled with the native MIPS compiler produced the
correct results.

Target type Example
----------- ---------------------------------------------------
int          2.14748e+09 =>  2147483647 (INT_MAX)
int         -2.14748e+09 => -2147483648 (INT_MIN)
long long    2.14748e+09 =>  2147483648
long long   -2.14748e+09 => -2147483648
long long    9.22337e+18 => -9223372036854775808 (LONGLONG_MIN)
long long   -9.22337e+18 => -9223372036854775808 (LONGLONG_MIN)


Note that some of the results have the wrong sign.  Here are the results
produced by the native compiler, and by the GCC-compiled program after
it mysteriously started behaving.

Target type Example
----------- ---------------------------------------------------
int          2.14748e+09 =>  2147480000
int         -2.14748e+09 => -2147480000
long long    2.14748e+09 =>  2147480000
long long   -2.14748e+09 => -2147480000
long long    9.22337e+18 =>  9223370000000000000
long long   -9.22337e+18 => -9223370000000000000


------------------------------------------------------------------------
/* conversions.c
   Written by Jerry James
   Demonstrate failed floating point --> fixed point conversions
*/

#include <stdio.h>
#include <stdlib.h>

#define iprint(d)  printf("%g --> int == %d\n", d, (int)d)
#define dprint(d)  printf("%g --> long long == %lld\n", d, (long long)d)

#ifdef mips
extern const double __infinity;   /* This is defined in libc */
#define inf __infinity;
#else /* SPARC */
#define inf (1.0 / 0.0)
#endif /* mips */

int main()
{
  double d, d2;

  /* This section fails on both the MIPS II and SPARC V8 configurations */

  d =  1e+25; dprint(d);                /* Large positive value */
  d = -1e+25; dprint(d);                /* Large negative value */
  d =  inf;   dprint(d);                /* Positive infinity    */
  d = -d;     dprint(d);                /* Negative infinity    */

#ifdef mips
  /* This section exhibits intermittent failures on the MIPS II
     configuration only */

  d = atof( "2.1478e+09" ); dprint(d);  /* Near INT_MAX         */
  d = atof("-2.1478e+09" ); dprint(d);  /* Near INT_MIN         */
  d = atof( "9.22337e+18"); dprint(d);  /* Near LONGLONG_MAX    */
  d = atof("-9.22337e+18"); dprint(d);  /* Near LONGLONG_MIN    */
#endif /* mips */
}
------------------------------------------------------------------------

Regards,

Jerry James
Email: jerry@cs.ucsb.edu
WWW:   http://www.cs.ucsb.edu/~jerry/
Technical Details
Message-ID: <199612210059.QAA00805@amazon.cs.ucsb.edu>
Path: arc1-ca.pugleaf.net!unknown!not-for-mail

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 113d02,c57f5e1b1afed020,start
X-Google-Attributes: gid113d02,public
From: jerry@cs.ucsb.edu (Jeremiah W. James)
Subject: Floating point to long long conversions
Date: 1996/12/20
Message-ID: <199612210059.QAA00805@amazon.cs.ucsb.edu>
X-Deja-AN: 205191060
sender: bug-gcc-request@prep.ai.mit.edu
x-gateway: relay2.UU.NET from bug-gcc to gnu.gcc.bug; Fri, 20 Dec 1996 19:57:02 EST
reply-to: jerry@cs.ucsb.edu
newsgroups: gnu.gcc.bug