From: dragon@NSCVAX.PRINCETON.EDU (Mighty Firebreather)
Newsgroups: comp.os.vms
Subject: RE: VAX (F,D,G) Floating Point <=> IEEE Floating Point?
Date: 25 Jan 93 14:36:29 GMT
Distribution: world
Organization: The Internet


	James Harvey <harvey@iupui.edu> writes:
>
>Anyone have any routines to convert to/from the VAX (F,D,G) floating point
>formats and IEEE floating point formats?  Or just documentation on the IEEE
>floating point formats - then I could write it myself.  Either FORTRAN or C
>is OK for me.
>

	This subject was discussed several years ago and three people 
posted example which I saved.  I've enclosed them following my signature.

*************************************************************************
*                                                                       *
*                        Here, there be dragons!                        *
*                      dragon@nscvax.princeton.edu                      *
*                                                                       *
*                                                Richard B. Gilbert     *
*************************************************************************

Date: Thu, 28 Jul 88 10:57 EDT
From: Frank Manion <MANION@curie.rm.fccc.edu>
Subject: re: ieee to vax format
To: ghosh@prism.clemson.EDU, INFO-VAX@KL.SRI.COM
X-VMS-To: IN%"ghosh@prism.clemson.edu",IN-INFO-VAX,MANION

Please excuse the lateness of this reply, Info-vax seems a week delayed
in reaching me. Is this happening to anyone else???

Amitava Ghosh writes:
>does anyone know what the difference is between the IEEE floating
>point representation and the way the VAX stores numbers. If so
>how does one convert from one format to the other.  

I had to convert from ieee to vax format recently, and finding the information
in a readily available form was indeed a problem. The source I found
in the end was the MC68881 Floating-Point Coprocessor User's Manual. I
suggest anyone intrested obtain a copy of this manual from the Motorola
corporation.

The motorola chip, at least, supports single, double, extended precision,
and packed decimal real string data formats. I have included a routine,
written in fortran, to convert an IEEE single precision floating point
number to the Vax single precision F_floating form. The routine has
extensive comments which should provide some insight into the functioning of
both architectures.

For more information on the vax floating point number see the "Data
representation" chapter of the vax architecture handbook.

c fjm -- 11/6/87 -- Function IEEE_VAX_S(Value)
c
c This function takes an IEEE format MC68881 Single precision floating
c point number and returns the VAX F_floating form of the number if it
c is in range.
c
c Note: The smallest vax floating point number is 4 times smaller than
c       the smallest ieee floating point number in normallized form.
c	The largest vax floating point number is .5 times as large as
c	the largest ieee floating point number.
c
c	Actual ranges:
c
c		Vax			IEEE
c		---			----
c
c	max	1.7014119x10**38	3.4028243x10**38
c	min	0.29387365x10**-38	1.175495x10**-38 (normalized)
c					1.4013x10**-45   (de-normalized)
c
c Let E = the exponent part of the real (in signed magnitude form), and
c let M = the mantisa, and S = the sign. The vax represents floating point
c numbers as:
c
c	S bit -- bit 15
c	E     -- bits 7-14, 8 bit, excess 128 exponent.
c	M     -- bits 6(MSB)-0 and bits 31-16(LSB) unsigned fraction.
c       Numbers are stored in a normalized form with a hidden 1 bit
c	representing a 0.1 is immediately to the left of the MSB of M. Note
c	that the radix point of the fraction is to the left of the hidden
c	bit in this form.
c
c	IF E .ge. 1 then
c		value = (-1)**S x 2**(E-128) x 0.1M
c	IF S .eq. 0 .and. E .eq. 0 then
c		value = 0 (unsigned)
c	IF S .eq. 1 .and. E .eq. 0 then
c		illegal value, signalled on attempted operation.
c
c The IEEE representation is as follows:
c
c	S bit -- bit 31
c	E     -- bits 23-30, 8 bit, excess 127 binary exponent.
c	M     -- bits 22(MSB) - 0(LSB) unsigned fraction.
c	Numbers are stored in either normalized or de-normalized form. In
c       normalized form (the usual representation) a hidden 1 bit representing
c       a 1.0 is immediatly to the left of the MSB of M. In denormalized form,
c       the hidden bit is 0. See below. Note that in IEEE form, the radix point
c	of the fraction is to the right of the hidden bit.
c
c	IF E .ge. 1 .and. E .le. 254 then
c		actual value = (-1)**S x 2**(E-127) x 1.M
c	IF E .eq. 0 .and. M .eq. 0 then
c		value = signed zero (S bit is preserved)
c	IF E .eq. 255 .and. M .ne. 0 then
c		not a number (NAN). M can have any bit pattern, and the
c		result of any operation on a NAN with the MSB of F set
c		on an IEEE implementation results in a signal. The
c		interpretation on any value associated with a NAN is left
c		to the application.
c	IF E .eq. 255 .and. M .eq. 0 then
c		value = Plus or minus infinity, depending on S.
c	IF E .eq. 0 .and. M .ne. 0 then
c		denormalized number, used to represent numbers less 
c		than can be represented in normalized form. The hidden bit
c		is assumed to a zero.
c		value = (-1)**S x 2**(E-126) x 0.M
c
c Note that the vax and ieee forms differ by a bias of 1 in their stored
c exponent form, and that they also differ implicitly by a power of 2 due to
c the difference in normalization scalling (ieee = 1.M, vax = 0.1M).
c Thus the conversion for the exponent is Evax = Eieee + 2. Further, the vax
c can represent smaller numbers in normallized form than can the 68881, so
c this routine converts the de-normalized numbers that are representable
c on the vax. Thus, all ieee normalized numbers with exponents less than 254
c are convertable to vax representations. Further, Some of the de-normalized
c numbers are convertable. Loss of range (overflow) occurs on the high end.
c The actual conversion outline follows:
c
c Normallized numbers:
c
c	numbers in the magnitude of:
c		1.175495 x 10**-38 to 1.7014119 x 10**38
c	are converted exactly, with no loss of precision.
c
c	numbers with a magnitude greater than 1.7014119 x 10**38
c       are converted to a vax reserved operand with sign of 1 and
c	exponent and mantissa of zero. This is the equivalent of
c       the result of a floating overflow on a 780 class machine.
c
c De-normalized numbers:
c
c	numbers in the magnitude of:
c		0.29387365 x 10**-38 to 1.175494 x 10**-38
c	are converted. Note that while the conversion is exact,
c       the vax has 1 to 2 bits more precision in this range than is
c	represenatble in the ieee form. The extra 1 or 2 bits are assigned
c       zeros in the conversion.
c
c	numbers less than 0.29387365 x10**-38 are mapped on to vax zero
c	with S=0, E=0, and M=0.
c
c Zeros:
c
c	both positive and minus zero in the ieee implementation are
c	mapped on to vax zero with S=0, M=0, and E=0.
c
c Infinities:
c
c	Infinities have no dual in the vax architecture, as such, the
c	value mapped is a vax reserved operand, with S=1, E=0, and M=0.
c	This is the equivalent of a floating overflow result on the
c	780 class machines.
c
c Not Numbers (NAN's):
c
c	These are mapped onto vax operands by setting the sign bit,
c	clearing the exponent, and preserving the mantissa. Note that
c	this conversion losses the original sign bit. The ieee representation
c       has twice as many NAN's as the vax, so half are lost.
c

	integer*4 function IEEE_VAX_S(value) ! really of type bit vector.

	implicit	none

	integer*4 	value

	integer*4 	S
	integer*4 	E
	integer*4 	M

	integer*4 	lib$extzv

c Fetch the fields from IEEE format:
c
c	31 30          23 22                           0
c      +--+--------------+------------------------------+
c      | S| Exponent     |MSB   Mantissa             LSB|
c      +--+--------------+------------------------------+
c
	S = lib$extzv(31,1,value)
	E = lib$extzv(23,8,value)
	M = lib$extzv(0,23,value)

c Note: The following code is optimized to deal with the two most likely
c       casses first: namely, normal values and zeros.
c

c Zeros and de-normalized numbers:

	if ( E .eq. 0 ) then

c Zeros:
	  if( M .eq. 0 ) then
	    S = 0

c de-normalized number:

	  else ! M .ne. 0

c          number is representable if  bit 21 or 22 is set.
c          shift the mantisa the right number of bits and strip the
c          high order set bit which becomes the hidden bit on the vax.
c          Numbers outside the representable range are set to zero.

	    if ( ( M .and. '400000'x) .ne. 0 ) then
	      M = (M .or. '3FFFFF'x) * 2
	      E = 2
	    else if ( ( M .and. '200000'x) .ne. 0 ) then
	      M = (M .or. '1FFFFF'x) * 4
	      E = 1
	    else
	      S = 0
	      E = 0
	      M = 0
	      end if
	    end if

c Normal value:

	else if ( E .lt. 254 ) then
	  E = E + 2


c un-representable (overflow)

	else if ( E .eq. 254 ) then
	  S = 1
	  E = 0
	  M = 0

c Infinities and NAN's

	else ! E .eq. 255
	  S = 1
	  E = 0

	  end if

c Store the numbers in vax format.
c
c	31                   16 15 14       7 6           0
c      +-----------------------+--+----------+-------------+
c      |    Mantissa        LSB| S| Exponent |MSB Mantissa |
c      +-----------------------+--+----------+-------------+
c
	call lib$insv(S,15,1,ieee_vax_s)
	call lib$insv(E, 7,8,ieee_vax_s)
	call lib$insv(lib$extzv(16,7,M),0,7,ieee_vax_s)
	call lib$insv(lib$extzv(0,16,M),16,16,ieee_vax_s)

	return
	end
:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:
Reply to:
  MANION@CURIE.RM.FCCC.EDU              Frank J. Manion
                                        The Fox Chase Cancer Center
  Phone: (215) 728-3660                 7701 Burholme Avenue
                                        Philadelphia, PA  19111
                                        USA
:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:

Date: 22 Jul 88 22:37:55 GMT
From: acdpyr!pack@handies.ucar.edu  (Dan Packman)
Organization: Atmospheric Chemistry Division/NCAR, Boulder CO
Subject: Re: difference between vax floating point representation and IEEE
Message-Id: <471@ncar.ucar.edu>
To: info-vax@kl.sri.com

In article <2256@hubcap.UUCP> ghosh@hubcap.UUCP (Amitava Ghosh) writes:
>does anyone know what the difference is between the IEEE floating
>point representation and the way the VAX stores numbers. If so
>how does one convert from one format to the other...
The following program converts from vax f format to IEEE (UNIX point of view)
--------cut here-------------
      subroutine vax2lcl(n,iarray)
      dimension iarray(n)
      character*1 conv(4),ccc
      integer iconv
      equivalence (iconv,conv)
c Convert from vax floating point f format to pyramid IEEE single
      do 10 i=1,n
        iconv=iarray(i)
        if (iconv.ne.0) then
         ccc=conv(1)
         iii=ichar(conv(2))-1
         if (iii.lt.0)then
           write(0,100)iconv
 100       format(' vax2lcl: overflow int in =',i10)
           call exit(1)
         endif
         conv(1)=char(iii)
         conv(2)=ccc
         ccc=conv(3)
         conv(3)=conv(4)
         conv(4)=ccc
         iarray(i)=iconv
        endif
  10  continue
      return
      end
--------cut here-------------
The following converts an array of IEEE single floats to vax floats
It is written to work on a VAX/VMS machine
--------cut here-------------
      subroutine pyr2lcl(n,iarray)
      dimension iarray(n)
      byte conv(4),ccc
      integer iconv
      equivalence (iconv,conv)
c Convert from pyramid IEEE single to vax floating point f format
      do 10 i=1,n
        iconv=iarray(i)
        if (iconv.ne.0) then
         ccc=conv(2)
         iii=conv(1)+1
         if (iii.gt.255)then
           write(0,100)iconv
 100       format(' pyr2lcl: overflow int in =',i10)
           call exit(1)
         endif
         conv(2)=iii
         conv(1)=ccc
         ccc=conv(3)
         conv(3)=conv(4)
         conv(4)=ccc
         iarray(i)=iconv
        endif
  10  continue
      return
      end

Date: 2 Aug 88 15:07:00 CST
From: "MARTIN J. MOORE" <mooremj@eglin-vax.arpa>
Subject: Conversion between VAX and IEEE floating point
To: "info-vax" <info-vax@kl.sri.com>
cc: mooremj     
Reply-To: "MARTIN J. MOORE" <mooremj@eglin-vax.arpa>

Someone recently asked about converting VAX floating-point numbers to IEEE 
standard floating-point numbers.  I have run across a mildly bizarre hack for 
performing this conversion when (1) the numbers are single precision (32-bit) 
in both cases; and (2) the destination machine requires 32-bit quantities
to be specified high-word, low-word (opposite to the VAX, which is low-word,
high-word.)  For example, 68000-based machines.

The formulas are simply:

	IEEE number = VAX number * 0.25 
	VAX number = IEEE number * 4.0

with the caveat that the multiplication is performed *on the VAX*.

				Marty Moore
------