From: sani@att.com (Sani Nassif [227])
Subject: Re: vax floating point bit structure
Organization: AT&T
Date: Tue, 1 Sep 1992 11:36:17 GMT
X-Newsreader: Tin 1.1 PL5

Randy Byrne (zrwb14@hou.amoco.com) wrote:

: Since this is just about the largest "comp" user group I thought I'd try
: posting this question here:  Does anyone know what the bit structure of a
: VAX floating point number is?  The only information I have so far is that
: each word of the byte sequence is reversed i.e. 1032, not 0123.  I need to
: know which bit is the sign bit, are the exponent and/or the mantissa
: normalized (i.e. is some number added to the exponent or mantissa), is the
: exponent base 2,8, or 16, is the two's compliament of the exponent antissa
: used instead of the "plain" binary number, etc., etc.  If you can help
: please respond by private E-mail or post back to "comp.lang.c" (I have to
: write a translation in C).  Thanks in advance.	 :  : Randy : 

Here is a data structure that allows one to split apart a double both
on a SUN and on a VAX 780. "sign" and "exponent" are obvious, "f1..4"
are the mantissa. "Doffset" is the offset for the exponent and "FWIDTH"
is the width of the mantissa. I forget now if the mantissa is stored in
2s complement or not...

<< CODE <<
#ifdef SUN
typedef union {
    double NUMBER;
    struct {
	short unsigned sign:1, exponent:11, f1:4;
	short unsigned f2, f3, f4;
    } EXPLODE;
} ieee_double;
#define Doffset		1024
#define DHUGE		(double)0.50e+308
#define FWIDTH		52
#endif

#ifdef VAX
typedef union {
    double NUMBER;
    struct {
	short unsigned f1:7, exponent:8, sign:1;
	short unsigned f2, f3, f4;
    } EXPLODE;
  } ieee_double;
#define Doffset		128
#define DHUGE		(double)0.50e+38
#define FWIDTH		55
#endif
<< CODE <<

To illustrate use, this is an implementation of "modf" for a VAX:

<< CODE <<
/* *********************************************************** */
typedef union {
    double NUMBER;
    struct {
	short unsigned f1, f2, f3, f4;
    } UI;
    struct {
	short unsigned f1:7, exponent:8, sign:1;
	short unsigned f2, f3, f4;
    } EXPLODE;
  } ieee_double;

#define Doffset		128
#define FWIDTH		55
#define SIGN		0x8000
#define ISIGN		0x7FFF
#define EXPONENT	0x7F80
#define IEXPONENT	0x807F
#define EXPOFFSET	0x4000
#define DHUGE		(double)0.50e+38
#define DZERO		(double)0.0
#define MSBmask		0x8000
/* ************************************************** */
shift(x)
ieee_double *x;
{
    x -> UI.f1 = x -> UI.f1 << 1;
    if (x -> UI.f2 & MSBmask)
	x -> UI.f1 |= 01;
    x -> UI.f2 = x -> UI.f2 << 1;
    if (x -> UI.f3 & MSBmask)
	x -> UI.f2 |= 01;
    x -> UI.f3 = x -> UI.f3 << 1;
    if (x -> UI.f4 & MSBmask)
	x -> UI.f3 |= 01;
    x -> UI.f4 = x -> UI.f4 << 1;
}
/* ************************************************** */
double normalise_ieee(x)
ieee_double x;
{
    ieee_double y;
    int i = Doffset;
    y = x;
    if (y.UI.f1 & 0x0080) {
	y.EXPLODE.exponent = i;
	y.EXPLODE.sign = 0;
	return(y.NUMBER);
    }
    --i;
    y.UI.f1 &= 0x007f;
    while ((! (y.UI.f1 & 0x0040)) && i) {
	shift(&y);
	--i;
    }
    shift(&y);
    y.UI.f1 &= 0x007f;
    y.EXPLODE.exponent = i;
    return(y.NUMBER);
}
/* ************************************************** */
double modf(x, ipart)
double x, *ipart;
{
    int sign, e, i;
    ieee_double y;
    double fpart;
/* put in explode structure */
    y.NUMBER = x;
/* set sign to zero */
    sign = y.EXPLODE.sign;
    y.EXPLODE.sign = 0;
/* set exponent to zero */
    e = y.EXPLODE.exponent - Doffset;
    y.EXPLODE.exponent = 0;
/* if exponent shift is less than or zero, then the number is < 1 */
    if (e <= 0) {
	if (sign) {
	    *ipart = (double) -1.0;
	    return(1.0 - x);
	}
	else {
	    *ipart = (double)0.0;
	    return(x);
	}
    }
    if (e >= FWIDTH) {
	*ipart = x;
	return( (double)0.0 );
    }
    for (i = 1; i <= e; i++)
	shift(&y);
    fpart = normalise_ieee(y);
    if (sign) {
	*ipart = x + fpart - 1.0;
	fpart = 1.0 - fpart;
    }
    else
	*ipart = x - fpart;
    return(fpart);
}
<< CODE <<

I hope this is useful.
Sani.

----------------------------------------------------------------------
Sani R. Nassif
(sani.nassif@att.com)
----------------------------------------------------------------------