SUMMARY: Floatin Point conversion

From: Frode Stromsvag (frode@read-well.no)
Date: Sun Feb 04 1996 - 07:21:46 CST


Original question:

----- Begin Included Message -----

Help!

I have a 1/2" 9track tape with some data I need
to put on disk. On the tape some data is
represented as VAX F Floating Point values.
I need to have them converted to the SPARC
floating point format (which conforms to the
IEEE standard, I believe).

My question is: Is there any free available
sourcecode avaiable for conversion between
different floating point formats (IEEE,VAX,IBM)?

Thanks in advance.
I'll summarize.

----- End Included Message -----

Thanks to you help I could quickly program this thing.

Casper Dik casper@holland.sum.com
Patrick L. Nolan pln@egret1.Stanford.EDU
Glen Satchell Glenn.Satchell@uniq.com.au
Keith Bierman khb@gammara.eng.sun.com
Scott C. Allendorf scott-allendorf@uiowa.edu

Most mentioned the function 'convert_external' which is included
in the more recent versions of Sun C or Sun Fortran compilers.
Unfortunately (I shoule have mentioned it) the configuration
was SunOS 4.1.3 with Sun Fortran 1.3 (!!).

Casper Dik sent me this answer:

----- Begin Included Message -----

This is xdr_float.h from sunrpc 4.0.

It contains code to convert from VAXFP to xdr FP (on the VAX, so you need
to edit it to get the endianess right)

Hope this helps (it's part of SunRPC 4.0)

#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: rpc/xdr_float.c
# Wrapped by casper on Thu Feb 1 10:42:28 1996
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'rpc/xdr_float.c' -a "${1}" != "-c" ; then
  echo shar: Will not clobber existing file \"'rpc/xdr_float.c'\"
else
echo shar: Extracting \"'rpc/xdr_float.c'\" \(6921 characters\)
sed "s/^X//" >'rpc/xdr_float.c' <<'END_OF_FILE'
X/* @(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC */
X/*
X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
X * unrestricted use provided that this legend is included on all tape
X * media and as a part of the software program in whole or part. Users
X * may copy or modify Sun RPC without charge, but are not authorized
X * to license or distribute it to anyone else except as part of a product or
X * program developed by the user.
X *
X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
X *
X * Sun RPC is provided with no support and without any obligation on the
X * part of Sun Microsystems, Inc. to assist in its use, correction,
X * modification or enhancement.
X *
X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
X * OR ANY PART THEREOF.
X *
X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
X * or profits or other special, indirect and consequential damages, even if
X * Sun has been advised of the possibility of such damages.
X *
X * Sun Microsystems, Inc.
X * 2550 Garcia Avenue
X * Mountain View, California 94043
X */
X#if !defined(lint) && defined(SCCSIDS)
Xstatic char sccsid[] = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";
X#endif
X
X/*
X * xdr_float.c, Generic XDR routines impelmentation.
X *
X * Copyright (C) 1984, Sun Microsystems, Inc.
X *
X * These are the "floating point" xdr routines used to (de)serialize
X * most common data items. See xdr.h for more info on the interface to
X * xdr.
X */
X
X#include <stdio.h>
X
X#include <rpc/types.h>
X#include <rpc/xdr.h>
X
X/*
X * NB: Not portable.
X * This routine works on Suns (Sky / 68000's) and Vaxen.
X */
X
X#ifdef vax
X
X/* What IEEE single precision floating point looks like on a Vax */
Xstruct ieee_single {
X unsigned int mantissa: 23;
X unsigned int exp : 8;
X unsigned int sign : 1;
X};
X
X/* Vax single precision floating point */
Xstruct vax_single {
X unsigned int mantissa1 : 7;
X unsigned int exp : 8;
X unsigned int sign : 1;
X unsigned int mantissa2 : 16;
X};
X
X#define VAX_SNG_BIAS 0x81
X#define IEEE_SNG_BIAS 0x7f
X
Xstatic struct sgl_limits {
X struct vax_single s;
X struct ieee_single ieee;
X} sgl_limits[2] = {
X {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */
X { 0x0, 0xff, 0x0 }}, /* Max IEEE */
X {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
X { 0x0, 0x0, 0x0 }} /* Min IEEE */
X};
X#endif /* vax */
X
Xbool_t
Xxdr_float(xdrs, fp)
X register XDR *xdrs;
X register float *fp;
X{
X#if !defined(mc68000) && !defined(sparc)
X struct ieee_single is;
X struct vax_single vs, *vsp;
X struct sgl_limits *lim;
X int i;
X#endif
X switch (xdrs->x_op) {
X
X case XDR_ENCODE:
X#if defined(mc68000) || defined(sparc)
X return (XDR_PUTLONG(xdrs, (long *)fp));
X#else
X vs = *((struct vax_single *)fp);
X for (i = 0, lim = sgl_limits;
X i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
X i++, lim++) {
X if ((vs.mantissa2 == lim->s.mantissa2) &&
X (vs.exp == lim->s.exp) &&
X (vs.mantissa1 == lim->s.mantissa1)) {
X is = lim->ieee;
X goto shipit;
X }
X }
X is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
X is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
X shipit:
X is.sign = vs.sign;
X return (XDR_PUTLONG(xdrs, (long *)&is));
X#endif
X
X case XDR_DECODE:
X#if defined(mc68000) || defined(sparc)
X return (XDR_GETLONG(xdrs, (long *)fp));
X#else
X vsp = (struct vax_single *)fp;
X if (!XDR_GETLONG(xdrs, (long *)&is))
X return (FALSE);
X for (i = 0, lim = sgl_limits;
X i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
X i++, lim++) {
X if ((is.exp == lim->ieee.exp) &&
X (is.mantissa == lim->ieee.mantissa)) {
X *vsp = lim->s;
X goto doneit;
X }
X }
X vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
X vsp->mantissa2 = is.mantissa;
X vsp->mantissa1 = (is.mantissa >> 16);
X doneit:
X vsp->sign = is.sign;
X return (TRUE);
X#endif
X
X case XDR_FREE:
X return (TRUE);
X }
X return (FALSE);
X}
X
X/*
X * This routine works on Suns (Sky / 68000's) and Vaxen.
X */
X
X#ifdef vax
X/* What IEEE double precision floating point looks like on a Vax */
Xstruct ieee_double {
X unsigned int mantissa1 : 20;
X unsigned int exp : 11;
X unsigned int sign : 1;
X unsigned int mantissa2 : 32;
X};
X
X/* Vax double precision floating point */
Xstruct vax_double {
X unsigned int mantissa1 : 7;
X unsigned int exp : 8;
X unsigned int sign : 1;
X unsigned int mantissa2 : 16;
X unsigned int mantissa3 : 16;
X unsigned int mantissa4 : 16;
X};
X
X#define VAX_DBL_BIAS 0x81
X#define IEEE_DBL_BIAS 0x3ff
X#define MASK(nbits) ((1 << nbits) - 1)
X
Xstatic struct dbl_limits {
X struct vax_double d;
X struct ieee_double ieee;
X} dbl_limits[2] = {
X {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */
X { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */
X {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */
X { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */
X};
X
X#endif /* vax */
X
X
Xbool_t
Xxdr_double(xdrs, dp)
X register XDR *xdrs;
X double *dp;
X{
X register long *lp;
X#if !defined(mc68000) && !defined(sparc)
X struct ieee_double id;
X struct vax_double vd;
X register struct dbl_limits *lim;
X int i;
X#endif
X
X switch (xdrs->x_op) {
X
X case XDR_ENCODE:
X#if defined(mc68000) || defined(sparc)
X lp = (long *)dp;
X#else
X vd = *((struct vax_double *)dp);
X for (i = 0, lim = dbl_limits;
X i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
X i++, lim++) {
X if ((vd.mantissa4 == lim->d.mantissa4) &&
X (vd.mantissa3 == lim->d.mantissa3) &&
X (vd.mantissa2 == lim->d.mantissa2) &&
X (vd.mantissa1 == lim->d.mantissa1) &&
X (vd.exp == lim->d.exp)) {
X id = lim->ieee;
X goto shipit;
X }
X }
X id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
X id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
X id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
X (vd.mantissa3 << 13) |
X ((vd.mantissa4 >> 3) & MASK(13));
X shipit:
X id.sign = vd.sign;
X lp = (long *)&id;
X#endif
X return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
X
X case XDR_DECODE:
X#if defined(mc68000) || defined(sparc)
X lp = (long *)dp;
X return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp));
X#else
X lp = (long *)&id;
X if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
X return (FALSE);
X for (i = 0, lim = dbl_limits;
X i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
X i++, lim++) {
X if ((id.mantissa2 == lim->ieee.mantissa2) &&
X (id.mantissa1 == lim->ieee.mantissa1) &&
X (id.exp == lim->ieee.exp)) {
X vd = lim->d;
X goto doneit;
X }
X }
X vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
X vd.mantissa1 = (id.mantissa1 >> 13);
X vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
X (id.mantissa2 >> 29);
X vd.mantissa3 = (id.mantissa2 >> 13);
X vd.mantissa4 = (id.mantissa2 << 3);
X doneit:
X vd.sign = id.sign;
X *dp = *((double *)&vd);
X return (TRUE);
X#endif
X
X case XDR_FREE:
X return (TRUE);
X }
X return (FALSE);
X}
END_OF_FILE
if test 6921 -ne `wc -c <'rpc/xdr_float.c'`; then
    echo shar: \"'rpc/xdr_float.c'\" unpacked with wrong size!
fi
chmod +x 'rpc/xdr_float.c'
# end of 'rpc/xdr_float.c'
fi
echo shar: End of shell archive.
exit 0

----- End Included Message -----



This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:10:52 CDT