Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!ncar!ames!sgi!tarolli@riva.esd.sgi.com From: tarolli@riva.esd.sgi.com (Gary Tarolli) Newsgroups: comp.sys.sgi Subject: Re: Binary representation of REAL #'s VAX vs.IRIS Summary: VAX to IEEE conversion routines Message-ID: <47538@sgi.sgi.com> Date: 5 Jan 90 16:47:02 GMT References: <90Jan4.144239est.57496@ugw.utcs.utoronto.ca> Sender: tarolli@riva.esd.sgi.com Organization: Silicon Graphics, Inc., Mountain View, CA Lines: 134 In article <90Jan4.144239est.57496@ugw.utcs.utoronto.ca>, SERRER@nrcm3.nrc.ca (Martin Serrer - Systems Manager) writes: > Hello all, > I asked this list sometime ago about moving binary files from a VAX to our > IRIS 4D50 via 4DDN and I thank you for the replies recieved. > I have another problem now. > These files were created on the VAX with a piece of FORTRAN code. The records > are were written as unformatted REAL*4 (F_floating) ie. four bytes arranged as > follows. > > bits 15 14 7 6 0 > +-----------------------------------------------+ > |sign| exponent | fraction | > +-----------------------------------------------+ > | fraction | > +-----------------------------------------------+ > bits 31 16 > > I need to read these data files with a C program on the IRIS. Has anyone > written such a piece of code?? How are reals stored on the IRIS?? Reals are stored in IEEE format on the IRIS, with BIG_ENDIAN byte ordering. The following code can be used to convert both single and double precision floats to/from the VAX. It is an excerpt from the DGL source code. The single precision routines are simple enuf to understand, the doubles are quite messy. These routines were written to run on the VAX, so "hton" means host to network, or VAX to IEEE. Likewise, "ntoh" means network to host, or IEEE to VAX. However, I believe you can run them on the IRIS as well, assuming that the data file was not byte swapped when you copied over the network. If the 4DDN copying swapped bytes, then you simply have to adjust the indicies on the right side of the assignments. /*----------------------------------------------------------------------*/ /* CONVERSION routines for floats and doubles /*----------------------------------------------------------------------*/ /* can't use float pointers or VAX core dumps */ mem_hton_float (t,f) long *t,*f; { long _tobuf; char *_to = (char *)&_tobuf; if (*(long *)f != 0) { _to[0] = ((char *)f)[1]-1; _to[1] = ((char *)f)[0]; _to[2] = ((char *)f)[3]; _to[3] = ((char *)f)[2]; *t = _tobuf; } else *t = *f; } /* can't use float pointers or VAX core dumps */ mem_ntoh_float (t,f) register long *t,*f; { long _tobuf; char *_to = (char *)&_tobuf; if (*(long *)f != 0) { _to[0] = ((char *)f)[1]; _to[1] = ((char *)f)[0]+1; _to[2] = ((char *)f)[3]; _to[3] = ((char *)f)[2]; *t = _tobuf; } else *t = *f; } mem_hton_double (t,f) register long *t; register unsigned char *f; { register unsigned short exp; long _tobuf[2]; unsigned char *_to = (unsigned char *)_tobuf; if (((long *)f)[0] || ((long *)f)[1]) { exp = ((f[1] & 0x7f) << 1) | (f[0] >> 7); exp = exp -1-128+1023; /* adjust exponent */ _to[0] = (f[1] & 0x80) | (exp >> 4); _to[1] = (exp << 4) | ((f[0] & 0x7f) >> 3); _to[2] = (f[0] << 5) | (f[3] >> 3); _to[3] = (f[3] << 5) | (f[2] >> 3); _to[4] = (f[2] << 5) | (f[5] >> 3); _to[5] = (f[5] << 5) | (f[4] >> 3); _to[6] = (f[4] << 5) | (f[7] >> 3); _to[7] = (f[7] << 5) | (f[6] >> 3); t[0] = _tobuf[0]; /* copy data back */ t[1] = _tobuf[1]; } else { t[0] = ((long *)f)[0]; t[1] = ((long *)f)[1]; } } mem_ntoh_double (t,f) register long *t; register unsigned char *f; { register unsigned short exp; long _tobuf[2]; unsigned char *_to = (unsigned char *)_tobuf; if (((long *)f)[0] || ((long *)f)[1]) { exp = ((f[0] & 0x7f) << 4) | (f[1] >> 4); exp = exp +1+128-1023; /* adjust exponent */ _to[0] = (exp << 7) | ((f[1] & 0x0f) << 3) | (f[2] >> 5); _to[1] = (f[0] & 0x80) | ((exp & 0xfe) >> 1); _to[2] = (f[3] << 3) | (f[4] >> 5); _to[3] = (f[2] << 3) | (f[3] >> 5); _to[4] = (f[5] << 3) | (f[6] >> 5); _to[5] = (f[4] << 3) | (f[5] >> 5); _to[6] = (f[7] << 3) | 0; _to[7] = (f[6] << 3) | (f[7] >> 5); t[0] = _tobuf[0]; /* copy data back */ t[1] = _tobuf[1]; } else { t[0] = ((long *)f)[0]; t[1] = ((long *)f)[1]; } } -- Gary Tarolli