[comp.sys.sgi] Binary representation of REAL #'s VAX vs.IRIS

SERRER@nrcm3.nrc.ca (Martin Serrer - Systems Manager) (01/05/90)

Hello all,
  I asked this list sometime ago about moving binary files from a VAX to our
IRIS 4D50 via 4DDN and I thank you for the replies recieved.
  I have another problem now.
  These files were created on the VAX with a piece of FORTRAN code. The records
are were written as unformatted REAL*4 (F_floating) ie. four bytes arranged as
follows.

  bits   15    14                    7 6              0
        +-----------------------------------------------+
        |sign|       exponent         |    fraction     |
        +-----------------------------------------------+
        |          fraction                             |
        +-----------------------------------------------+
  bits   31                                           16

  I need to read these data files with a C program on the IRIS. Has anyone
written such a piece of code?? How are reals stored on the IRIS??
  Any help would be appreciated.
  I found the SWAP_*  and SEX routines in the programmers reference manual and
hoped that they might be of some use but they are not documented in a
particularly useful manner.
+-----------------------------------------------------------------------------+
| Martin Serrer                           Systems Lab., Bldg. M3, Montreal Rd.|
| 613-993-9442 (Bell)                     National Research Council of Canada,|
| serrer@syslab.nrc.ca (BITNET)           Ottawa,  Ontario,  Canada  K1A-0R6  |
+----------Software Rusts...------------------Rust never Sleeps...------------+

blbates@AERO4.LARC.NASA.GOV ("Brent L. Bates AAD/TAB MS294 x42854") (01/05/90)

   We have a 3130 and the FORTRAN manual shows how REALS and DOUBLE
PRECISION numbers are stored and I am pretty sure it is the same on
the 4D machines.  Below is that description:

   REAL and DOUBLE PRECISION data elements are represented according to
the proposed IEEE standard described in Computer magazine of March 1981.
The diagrams below illustrate the representation.

                   __________________________________________
REAL                 S     Exponent            Mantissa
                   ------------------------------------------
                    31     30    23     22                  0
                    |         |                   |
                   Sign       |         Mantissa(23 + 1 bits)
                           Exponent, biased by 127

                   __________________________________________
DOUBLE PRECISION     S     Exponent            Mantissa
                   ------------------------------------------
                    63     62    52     31                  0
                    |         |                   |
                   Sign       |         Mantissa(52 + 1 bits)
                           Exponent, biased by 1023

   The parts of REAL and DOUBLE PRECISION numbers are as follows:

 * a one-bit sign bit designated by "S" in diagrams above.  The sign
   bit is a 1 only if the number is negative.

 * a biased exponent.  The exponent is eight bits for a REAL number,
   and 11 bits for a DOUBLE PRECISION number.  The values of all zeros,
   and all ones, are reserved values for exponents.

 * a normalized mantissa, with the high-order 1 bit "hidden."  The
   mantissa is 23 bits for a REAL number, and is 52 bits for a DOUBLE
   PRECISION number.  A REAL or DOUBLE PRECISION number is represented
   by the form:

       exponent-bias
      2             x 1.fraction
   where fraction is the number of bits in the mantissa.

   Examples:
   ________________________________________
     Value       Real      DOUBLE PRECISION 
   ----------------------------------------
       +0      00000000    0000000000000000
       -0      80000000    8000000000000000

       +1      3f800000    3ff0000000000000
       -1      bf800000    bff0000000000000

       +2      40000000    4000000000000000
       +3      40400000    4008000000000000

   +Infinity   7f800000    7ff0000000000000
   -Infinity   ff800000    fff0000000000000

      NaN      7f8xxxxx    7ffxxxxxxxxxxxxx
   ----------------------------------------

   I hope this is of some help.
--

	Brent L. Bates
	NASA-Langley Research Center
	M.S. 294
	Hampton, Virginia  23665-5225
	(804) 864-2854
	E-mail: blbates@aero4.larc.nasa.gov or blbates@aero2.larc.nasa.gov

davea@quasar.wpd.sgi.com (David B. Anderson) (01/06/90)

In article <90Jan4.144239est.57496@ugw.utcs.utoronto.ca>, SERRER@nrcm3.nrc.ca (Martin Serrer - Systems Manager) writes:
[other lines deleted]
> written such a piece of code?? How are reals stored on the IRIS??

Like all MIPS based machines, the 4D format is ANSI/IEEE Std 754-1985.

	IEEE Standard for Binary Floating-Point Arithmetic

Fortran REAL is stored as what the standard calls Single (32 bit).
Fortran DOUBLE PRECISION is stored as what the standard calls Double (64 bit).
See the standard for details.

Regards,
[ David B. Anderson  Silicon Graphics  (415)335-1548  davea@sgi.com ]

tarolli@riva.esd.sgi.com (Gary Tarolli) (01/06/90)

In article <90Jan4.144239est.57496@ugw.utcs.utoronto.ca>, SERRER@nrcm3.nrc.ca (Martin Serrer - Systems Manager) writes:
> Hello all,
>   I asked this list sometime ago about moving binary files from a VAX to our
> IRIS 4D50 via 4DDN and I thank you for the replies recieved.
>   I have another problem now.
>   These files were created on the VAX with a piece of FORTRAN code. The records
> are were written as unformatted REAL*4 (F_floating) ie. four bytes arranged as
> follows.
> 
>   bits   15    14                    7 6              0
>         +-----------------------------------------------+
>         |sign|       exponent         |    fraction     |
>         +-----------------------------------------------+
>         |          fraction                             |
>         +-----------------------------------------------+
>   bits   31                                           16
> 
>   I need to read these data files with a C program on the IRIS. Has anyone
> written such a piece of code?? How are reals stored on the IRIS??

Reals are stored in IEEE format on the IRIS, with BIG_ENDIAN byte ordering.
The following code can be used to convert both single and double precision
floats to/from the VAX. It is an excerpt from the DGL source code.  The 
single precision routines are simple enuf to understand, the doubles are
quite messy.

These routines were written to run on the VAX, so "hton" means host to
network, or VAX to IEEE.  Likewise, "ntoh" means network to host, or
IEEE to VAX.  However, I believe you can run them on the IRIS as well,
assuming that the data file was not byte swapped when you copied over
the network.  If the 4DDN copying swapped bytes, then you simply have
to adjust the indicies on the right side of the assignments.

/*----------------------------------------------------------------------*/
/* CONVERSION routines for floats and doubles
/*----------------------------------------------------------------------*/

/* can't use float pointers or VAX core dumps	*/
mem_hton_float (t,f)
    long *t,*f;
{
    long _tobuf;
    char *_to = (char *)&_tobuf;

    if (*(long *)f != 0) {
	_to[0] = ((char *)f)[1]-1;
	_to[1] = ((char *)f)[0];
	_to[2] = ((char *)f)[3];
	_to[3] = ((char *)f)[2];
	*t = _tobuf;
    }
    else *t = *f;
}

/* can't use float pointers or VAX core dumps	*/
mem_ntoh_float (t,f)
    register long *t,*f;
{
    long _tobuf;
    char *_to = (char *)&_tobuf;

    if (*(long *)f != 0) {
	_to[0] = ((char *)f)[1];
	_to[1] = ((char *)f)[0]+1;
	_to[2] = ((char *)f)[3];
	_to[3] = ((char *)f)[2];
	*t = _tobuf;
    }
    else *t = *f;
}

mem_hton_double (t,f)
    register long *t;
    register unsigned char *f;
{
    register unsigned short exp;
    long _tobuf[2];
    unsigned char *_to = (unsigned char *)_tobuf;

    if (((long *)f)[0] || ((long *)f)[1]) {
	exp = ((f[1] & 0x7f) << 1) | (f[0] >> 7);
	exp = exp -1-128+1023;		/* adjust exponent	*/

	_to[0] = (f[1] & 0x80) | (exp >> 4);
	_to[1] = (exp << 4) | ((f[0] & 0x7f) >> 3);
	_to[2] = (f[0] << 5) | (f[3] >> 3);
	_to[3] = (f[3] << 5) | (f[2] >> 3);

	_to[4] = (f[2] << 5) | (f[5] >> 3);
	_to[5] = (f[5] << 5) | (f[4] >> 3);
	_to[6] = (f[4] << 5) | (f[7] >> 3);
	_to[7] = (f[7] << 5) | (f[6] >> 3);

	t[0] = _tobuf[0];		/* copy data back	*/
	t[1] = _tobuf[1];
    }
    else {
	t[0] = ((long *)f)[0];
	t[1] = ((long *)f)[1];
    }
}

mem_ntoh_double (t,f)
    register long *t;
    register unsigned char *f;
{
    register unsigned short exp;
    long _tobuf[2];
    unsigned char *_to = (unsigned char *)_tobuf;

    if (((long *)f)[0] || ((long *)f)[1]) {
	exp = ((f[0] & 0x7f) << 4) | (f[1] >> 4);
	exp = exp +1+128-1023;		/* adjust exponent	*/

	_to[0] = (exp << 7) | ((f[1] & 0x0f) << 3) | (f[2] >> 5);
	_to[1] = (f[0] & 0x80) | ((exp & 0xfe) >> 1);
	_to[2] = (f[3] << 3) | (f[4] >> 5);
	_to[3] = (f[2] << 3) | (f[3] >> 5);

	_to[4] = (f[5] << 3) | (f[6] >> 5);
	_to[5] = (f[4] << 3) | (f[5] >> 5);
	_to[6] = (f[7] << 3) | 0;
	_to[7] = (f[6] << 3) | (f[7] >> 5);

	t[0] = _tobuf[0];		/* copy data back	*/
	t[1] = _tobuf[1];
    }
    else {
	t[0] = ((long *)f)[0];
	t[1] = ((long *)f)[1];
    }
}
--
						Gary Tarolli