[comp.unix.ultrix] Routine to convert between IEEE and VAX floating point ?

dan@rna.UUCP (Dan Ts'o) (05/29/90)

	Does anyone have a C routine to convert from IEEE floating point
to VAX D format floating point ?
	Failing that or anything similar, does anyone have a concise
description of the IEEE floating point format so I can write my own routine...

	Please email responses. Thanks.

				Cheers,
				Dan Ts'o		212-570-7671
				Dept. Neurobiology	dan@rna.rockefeller.edu
				Rockefeller Univ.	...cmcl2!rna!dan
				1230 York Ave.		rna!dan@nyu.edu
				NY, NY 10021		tso@rockefeller.arpa
							tso@rockvax.bitnet

mf@uunet.UU.NET (Michel Fingerhut) (05/29/90)

There is a set of undocumented such routines in UWS 2.0 (see release notes p. 78).

tody@noao.edu (Doug Tody CCS) (06/03/90)

From article <1023@rna.UUCP>, by dan@rna.UUCP (Dan Ts'o):
> 
> 	Does anyone have a C routine to convert from IEEE floating point
> to VAX D format floating point ?

This depends upon what cpu you want to perform the conversion on.  If you
want to convert to or from IEEE on a VAX cpu then I have some VAX assembler
routines which can do this (more efficiently than in C, due to the need to
bit shift a 64 bit quantity).

> 	Failing that or anything similar, does anyone have a concise
> description of the IEEE floating point format so I can write my own routine...

The main reference is the IEEE floating standard document.  I don't have the
document number handy, but you can order it from IEEE.  An IEEE double is
64 bits like a VAX D double, but the exponent is 11 bits rather than 8 for
VAX D format (VAX G format is also 11 bits), there is a *4 (or /4) factor
due to a difference in the normalization of the mantissa, and the bytes are
spped.

Converting IEEE single to VAX F is much simpler, all you do is byte swap and
multiply or divide by 4.0.

-- 
Doug Tody, National Optical Astronomy Observatories, Tucson AZ, 602-325-9217
UUCP: {arizona,decvax,ncar}!noao!tody  or  uunet!noao.edu!tody 
Internet: tody@noao.edu             SPAN/HEPNET: NOAO::TODY (NOAO=5355)

bright@Data-IO.COM (Walter Bright) (06/05/90)

From article <1023@rna.UUCP>, by dan@rna.UUCP (Dan Ts'o):
< 	Does anyone have a C routine to convert from IEEE floating point
< to VAX D format floating point ?

Here's one I wrote to convert from VAX to PC 64-bit doubles. You could
easily reverse it to go the other way.

main()
{
	double d1,d2;
	long *p;

	while (1)
	{	scanf(" %lf",&d1);
		p = (long *) &d1;
		printf("x%08lx,x%08lx\n",p[1],p[0]);
		vaxdbl_to_pcdbl(&d1,&d2);
		p = (long *) &d2;
		printf("x%08lx,x%08lx\n",p[1],p[0]);
	}
}

vaxdbl_to_pcdbl(pvax,ppc)
unsigned long *pvax,*ppc;
{
	unsigned sign,exponent;
	unsigned long fraction;

	sign = (*pvax & 0x8000) != 0;
	exponent = (*pvax >> 7) & 0xFF;
	fraction = ((*pvax & 0x7F) << 16) | (*pvax >> 16);
	printf("sign = %d, exponent = x%x, fraction = x%lx\n",
		sign,exponent,fraction);
	if (sign == 0 && exponent == 0)
	{	ppc[0] = 0;
		ppc[1] = 0;
		return;
	}
	/* Put sign in result	*/
	ppc[1] = (unsigned long) sign << 31;
	/* Compute new exponent	*/
	exponent += 0x3FF - 0x80 - 1;
	ppc[1] |= (unsigned long) exponent << 20;
	/* OR in fraction	*/
	ppc[1] |= (fraction >> 3);
	ppc[0] = (fraction << 29) | (pvax[1] >> 3);
}

wallyk@tekfdi.FDI.TEK.COM (Wally Kramer) (06/05/90)

This seems to be a subject which crops up from time to time.  I have
four routines which perform the following conversions:

	DEC F_FLOAT  to/from  IEEE ShortReal
	DEC D_FLOAT  to/from  IEEE LongReal

They are tested using the VAXC C compiler (from DEC), Turbo C 2.0, and
Green Hills C compiler for the 386.  As written, they do not appear to
work on Sun compilers for the 68000, but should be easy to modify for
this purpose.

They are written in ANSI C without the use of floating point instructions
(that is, no float or double declarations--just structure manipulations).

There is sufficient documentation to write the remaining conversions, or
to learn just about anything you want about either DEC or IEEE formats.

I'll be happy to email a copy to anyone who asks.  (I prefer Email
requests.  Use the phone only if your mailer can't reach me.)

wallyk@tekfdi.fdi.tek.com (Wally Kramer) 503 627 2363
Contractor from Step Technology, Inc.  503 244 1239

craigs@cognos.UUCP (Craig Statchuk) (06/07/90)

>From article <1023@rna.UUCP>, by dan@rna.UUCP (Dan Ts'o):
>> 
>> 	Does anyone have a C routine to convert from IEEE floating point
>> to VAX D format floating point ?
>

I had to do this a while back. I found it easiest to convert 
IEEE -> G_FLOAT ->D_FLOAT. As mentioned in another response all 
you have to do swap bytes and change the exponent to go from 
IEEE to G_FLOAT. The VAX RTL has the necessary routine to
change from G_FLOAT to D_FLOAT (and has another one if you wish to go
back).

Here's some code that will do the translation on the (using
bit fields yeah!):

union G_float_template {
  double asDouble;
  struct {
    unsigned long b1:16,b2:16,b3:16,b4:16;
  } asBits;
  struct {
    unsigned long mantissaL:20,exponent:11,sign:1,mantissaH:32;
  } asFields;
};

union G_float_template value;
unsigned short s_temp;
double result;
extern double MTH$CVT_G_D();
...
/* put some value into the template -- assume it is really in IEEE format */
value.asDouble = (IEEE) 1234.5

/* exchange upper 16 bits with lower 16 bits in each word */
s_temp = value.asBits.b1;
value.asBits.b1 = value.asBits.b2;
value.asBits.b2 = s_temp;
s_temp = value.asBits.b3;
value.asBits.b3 = value.asBit.b4;
value.asBits.b4 = s_temp;

/* normalize exponent bias */
if (value.asDouble != 0.0)
  net_value.asFields.exponent -= 2;

/* convert to D_FLOAT */
result = MTH$CVT_G_D(&value.asDouble);

Easy eh?

/CS



-- 
Craig Statchuk           USENET   : uunet!mitel!sce!cognos!craigs
Cognos Incorporated      INTERNET : craigs%cognos.uucp@uunet.uu.net
3755 Riverside Dr.       MaBellNET: (613) 738-1440
Ottawa, Ontario K1G 3Z4  FaxNET   : (613) 738-0002