From: rwh@moose.cccs.umn.edu (RICHARD HOFFBECK)
Newsgroups: comp.lang.c
Subject: Re: vax floating point bit structure
Date: 31 Aug 92 15:03:00 GMT
Reply-To: rwh@moose.cccs.umn.edu
Organization: Colon Cancer Control Study, University of Minnesota, Minneapolis
News-Software: VAX/VMS VNEWS 1.41

>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?  

It depends on which of the floating point formats was being used, i.e. G_FLOAT,
D_FLOAT, etc.

>The only information I have so far is that each word of the byte sequence 
>is reversed i.e. 1032, not 0123.  

I've only done the G_FLOAT format to IEEE conversion to write a .WKS file
from the VAX.  You need to take the G_FLOAT value, divide by 4 (to shift the
exponent), swap the ordering (bytes 0-7 become 7-0) and then swap each byte
pair. For the other formats you'll probably need to find the appropriate manual
from the gray wall.

I've tacked the conversion routine on to the end of the message.  Hope it
helps!

--rick

+-----------------------------------------------------------------+
| Richard Hoffbeck               INTERNET: rwh@moose.cccs.umn.edu |
| Colon Cancer Control Study     ATT     : (612) 627-4151         |
| University of Minnesota        CIS     : 72406,521              |
| Minneapolis, MN 55455                                           |
+-----------------------------------------------------------------+

______________________________________________________________________________

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

/*-------------------------
*  Floating Point Formats
*------------------------*/
#define	PROTECT		128
#define	FIXED		  0
#define	SCNTFC		 16
#define	CURRENCY	 32
#define	PERCENT		 48
#define	COMMA		 64
#define	SPECIAL		112

struct	FormatMap
{
	int	FormatMask ;
	char	FormatChar ;
} Formats[] =
	{
		FIXED,		'f',
		SCNTFC,		's',
		CURRENCY,	'$',
		PERCENT,	'%',
		COMMA,		',',
		SPECIAL,	'!'
	} ;

extern	FILE	*LotusOut ;
double	MTH$CVT_D_G() ;



/*---------------------------: MapFmtChar :---------------------------------+
*  RETURN the bitmask that corresponds to the specified formatting character|
*--------------------------------------------------------------------------*/
int	MapFmtChar( c )
	char	c ;
{
	int	i ;

	for( i = 0 ; i < 6 ; i++ )
		if( c == Formats[i].FormatChar )
			return Formats[i].FormatMask ;
	return 0xFF ;
}
	

/*--------------------------: LotusDbl :------------------------------------+
*  Write out a 8 byte double precision value to the file                    |
*--------------------------------------------------------------------------*/
char	LtDblData[] = {	'\016', '\000', '\015', '\000', '\000',	'\000',
		        '\000', '\000', '\000', '\000', '\000', '\000',
			'\000', '\000', '\000', '\000', '\000'} ;
void LotusDbl( row, col, d_value, DecPl, fmt )
	int	row ;		/* Row for the value to occupy		*/
	int	col ;		/* Col for the value to occupy		*/
 	double	d_value ;	/* Actual value to insert		*/
	int	DecPl ;		/* Number of decimal places to show	*/
 	char	*fmt ;		/* Format value for this cell		*/
{
	char	*s ;


	/*
	**  Fill in the header information for the number cell
	*/
	LtDblData[ 4] = (char) 0 ;
	LtDblData[ 4] = DecPl | MapFmtChar(fmt[0]) ;
	LtDblData[ 5] = col % 0xFF ;
	LtDblData[ 6] = col / 0xFF ;
	LtDblData[ 7] = row % 0xFF ;
	LtDblData[ 8] = row / 0xFF ;

	/*
	**  This is for the VAX to IEEE format conversion, bypass it on
	**  DOS based machines since they are already IEEE conformant.
	**
	**  The call to MTH$CVT_D_G is necessary since INGRESS uses the
	**  D_FLOAT format and Lotus wants IEEE which is almost the same
	**  as the DEC G_FLOAT format.  DON'T do anything to d_value
	**  after the conversion since VMS will treat the result as a
	**  D_FLOAT value.
	*/
#ifndef DOS
	d_value = d_value / (double) 4.0 ;
        d_value = MTH$CVT_D_G(&d_value) ;
	s = (char *) &d_value ;
	LtDblData[ 9] = s[6] ;
	LtDblData[10] = s[7] ;
	LtDblData[11] = s[4] ;
	LtDblData[12] = s[5] ;
	LtDblData[13] = s[2] ;
	LtDblData[14] = s[3] ;
	LtDblData[15] = s[0] ;
	LtDblData[16] = s[1] ;
#else
	s = (char *) &d_value ;
	LtDblData[ 9] = s[0] ;
	LtDblData[10] = s[1] ;
	LtDblData[11] = s[2] ;
	LtDblData[12] = s[3] ;
	LtDblData[13] = s[4] ;
	LtDblData[14] = s[5] ;
	LtDblData[15] = s[6] ;
	LtDblData[16] = s[7] ;
#endif
	fwrite( LtDblData, 17, 1, LotusOut ) ;
}
Newsgroups: comp.lang.c,comp.std.c