home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume6 / rpc2 / part09 / rpc / rpclib / xdr_float.c next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  6.5 KB  |  257 lines

  1. /*
  2.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  3.  * unrestricted use provided that this legend is included on all tape
  4.  * media and as a part of the software program in whole or part.  Users
  5.  * may copy or modify Sun RPC without charge, but are not authorized
  6.  * to license or distribute it to anyone else except as part of a product or
  7.  * program developed by the user.
  8.  * 
  9.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  10.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  11.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  12.  * 
  13.  * Sun RPC is provided with no support and without any obligation on the
  14.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  15.  * modification or enhancement.
  16.  * 
  17.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  18.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  19.  * OR ANY PART THEREOF.
  20.  * 
  21.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  22.  * or profits or other special, indirect and consequential damages, even if
  23.  * Sun has been advised of the possibility of such damages.
  24.  * 
  25.  * Sun Microsystems, Inc.
  26.  * 2550 Garcia Avenue
  27.  * Mountain View, California  94043
  28.  */
  29. #ifndef lint
  30. static char sccsid[] = "@(#)xdr_float.c 1.1 86/02/03 Copyr 1984 Sun Micro";
  31. #endif
  32.  
  33. /*
  34.  * xdr_float.c, Generic XDR routines impelmentation.
  35.  *
  36.  * Copyright (C) 1984, Sun Microsystems, Inc.
  37.  *
  38.  * These are the "floating point" xdr routines used to (de)serialize
  39.  * most common data items.  See xdr.h for more info on the interface to
  40.  * xdr.
  41.  */
  42.  
  43. #include "types.h"
  44. #include "xdr.h"
  45. #include <stdio.h>
  46.  
  47. /*
  48.  * NB: Not portable.
  49.  * This routine works on Suns (Sky / 68000's) and Vaxen.
  50.  */
  51.    
  52. /* What IEEE single precision floating point looks like on a Vax */
  53. struct  ieee_single {
  54.     unsigned int    mantissa: 23;
  55.     unsigned int    exp     : 8;
  56.     unsigned int    sign    : 1;
  57. };
  58.  
  59. /* Vax single precision floating point */
  60. struct  vax_single {
  61.     unsigned int    mantissa1 : 7;
  62.     unsigned int    exp       : 8;
  63.     unsigned int    sign      : 1;
  64.     unsigned int    mantissa2 : 16;
  65.         
  66. };
  67.  
  68. #define VAX_SNG_BIAS    0x81
  69. #define IEEE_SNG_BIAS   0x7f
  70.  
  71. static struct sgl_limits {
  72.     struct vax_single s;
  73.     struct ieee_single ieee;
  74. } sgl_limits[2] = {
  75.     {{ 0x3f, 0xff, 0x0, 0xffff },    /* Max Vax */
  76.     { 0x0, 0xff, 0x0 }},        /* Max IEEE */
  77.     {{ 0x0, 0x0, 0x0, 0x0 },    /* Min Vax */
  78.     { 0x0, 0x0, 0x0 }}        /* Min IEEE */
  79. };
  80.  
  81. bool_t 
  82. xdr_float(xdrs, fp)
  83.     register XDR *xdrs;
  84.     register float *fp;
  85. {
  86.     struct ieee_single is;
  87.     struct vax_single vs, *vsp;
  88.     struct sgl_limits *lim;
  89.     int i;
  90.  
  91.     switch (xdrs->x_op) {
  92.  
  93.     case XDR_ENCODE:
  94. #ifdef mc68000
  95.         return (XDR_PUTLONG(xdrs, (long *)fp));
  96. #else
  97.         vs = *((struct vax_single *)fp);
  98.         for (i = 0, lim = sgl_limits;
  99.             i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
  100.             i++, lim++) {
  101.             if ((vs.mantissa2 == lim->s.mantissa2) &&
  102.                 (vs.exp == lim->s.exp) &&
  103.                 (vs.mantissa1 == lim->s.mantissa1)) {
  104.                 is = lim->ieee;
  105.                 goto shipit;
  106.             }
  107.         }
  108.         is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
  109.         is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
  110.     shipit:
  111.         is.sign = vs.sign;
  112.         return (XDR_PUTLONG(xdrs, (long *)&is));
  113. #endif
  114.  
  115.     case XDR_DECODE:
  116. #ifdef mc68000
  117.         return (XDR_GETLONG(xdrs, (long *)fp));
  118. #else
  119.         vsp = (struct vax_single *)fp;
  120.         if (!XDR_GETLONG(xdrs, (long *)&is))
  121.             return (FALSE);
  122.         for (i = 0, lim = sgl_limits;
  123.             i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
  124.             i++, lim++) {
  125.             if ((is.exp == lim->ieee.exp) &&
  126.                 (is.mantissa = lim->ieee.mantissa)) {
  127.                 *vsp = lim->s;
  128.                 goto doneit;
  129.             }
  130.         }
  131.         vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
  132.         vsp->mantissa2 = is.mantissa;
  133.         vsp->mantissa1 = (is.mantissa >> 16);
  134.     doneit:
  135.         vsp->sign = is.sign;
  136.         return (TRUE);
  137. #endif
  138.  
  139.     case XDR_FREE:
  140.         return (TRUE);
  141.     }
  142.     return (FALSE);
  143. }
  144.  
  145. /*
  146.  * This routine works on Suns (Sky / 68000's) and Vaxen.
  147.  */
  148.  
  149. /* What IEEE double precision floating point looks like on a Vax */
  150. struct  ieee_double {
  151.     unsigned int    mantissa1 : 20;
  152.     unsigned int    exp      : 11;
  153.     unsigned int    sign      : 1;
  154.     unsigned int    mantissa2 : 32;
  155. };
  156.  
  157. /* Vax double precision floating point */
  158. struct  vax_double {
  159.     unsigned int    mantissa1 : 7;
  160.     unsigned int    exp       : 8;
  161.     unsigned int    sign      : 1;
  162.     unsigned int    mantissa2 : 16;
  163.     unsigned int    mantissa3 : 16;
  164.     unsigned int    mantissa4 : 16;
  165. };
  166.  
  167. #define VAX_DBL_BIAS    0x81
  168. #define IEEE_DBL_BIAS   0x3ff
  169. #define MASK(nbits)     ((1 << nbits) - 1)
  170.  
  171. static struct dbl_limits {
  172.     struct  vax_double d;
  173.     struct  ieee_double ieee;
  174. } dbl_limits[2] = {
  175.     {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff },    /* Max Vax */
  176.     { 0x0, 0x7ff, 0x0, 0x0 }},            /* Max IEEE */
  177.     {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},        /* Min Vax */
  178.     { 0x0, 0x0, 0x0, 0x0 }}                /* Min IEEE */
  179. };
  180.  
  181. bool_t           
  182. xdr_double(xdrs, dp)
  183.     register XDR *xdrs;
  184.     double *dp;
  185. {
  186.     register long *lp;
  187.     struct  ieee_double id;
  188.     struct  vax_double vd;
  189.     register struct dbl_limits *lim;
  190.     int i;
  191.  
  192.     switch (xdrs->x_op) {
  193.  
  194.     case XDR_ENCODE:
  195. #ifdef mc68000
  196.         lp = (long *)dp;
  197. #else
  198.         vd = *((struct  vax_double *)dp);
  199.         for (i = 0, lim = dbl_limits;
  200.             i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
  201.             i++, lim++) {
  202.             if ((vd.mantissa4 == lim->d.mantissa4) &&
  203.                 (vd.mantissa3 == lim->d.mantissa3) &&
  204.                 (vd.mantissa2 == lim->d.mantissa2) &&
  205.                 (vd.mantissa1 == lim->d.mantissa1) &&
  206.                 (vd.exp == lim->d.exp)) {
  207.                 id = lim->ieee;
  208.                 goto shipit;
  209.             }
  210.         }
  211.         id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
  212.         id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
  213.         id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
  214.                 (vd.mantissa3 << 13) |
  215.                 ((vd.mantissa4 >> 3) & MASK(13));
  216.     shipit:
  217.         id.sign = vd.sign;
  218.         lp = (long *)&id;
  219. #endif
  220.         return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
  221.  
  222.     case XDR_DECODE:
  223. #ifdef mc68000
  224.         lp = (long *)dp;
  225.         return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp));
  226. #else
  227.         lp = (long *)&id;
  228.         if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
  229.             return (FALSE);
  230.         for (i = 0, lim = dbl_limits;
  231.             i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
  232.             i++, lim++) {
  233.             if ((id.mantissa2 == lim->ieee.mantissa2) &&
  234.                 (id.mantissa1 == lim->ieee.mantissa1) &&
  235.                 (id.exp == lim->ieee.exp)) {
  236.                 vd = lim->d;
  237.                 goto doneit;
  238.             }
  239.         }
  240.         vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
  241.         vd.mantissa1 = (id.mantissa1 >> 13);
  242.         vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
  243.                 (id.mantissa2 >> 29);
  244.         vd.mantissa3 = (id.mantissa2 >> 13);
  245.         vd.mantissa4 = (id.mantissa2 << 3);
  246.     doneit:
  247.         vd.sign = id.sign;
  248.         *dp = *((double *)&vd);
  249.         return (TRUE);
  250. #endif
  251.  
  252.     case XDR_FREE:
  253.         return (TRUE);
  254.     }
  255.     return (FALSE);
  256. }
  257.