⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ibmieee.c

📁 ieee 与 ibm 的数据之间的转换
💻 C
字号:
#include "ibmieee.h"/*--------------------------------------------------------------------- * *   FILE: ./ibmieee.c * *----------------------------------------------------------------------**   DESCRIPTION:*     Conversion from IBM to IEEE format*     Byte order is detected and accounted for using*     define constant 'L_ENDIAN'**----------------------------------------------------------------------*   ROUTINES DEFINED IN THIS MODULE:                                 *----------------------------------------------------------------------** *  Convert IBM to IEEE integer:**   ibm_ieee_i( n, ibm, ieee)*   int n;*   int *ibm;*   int *ieee;* *  Convert IEEE to IBM integer:**   ieee_ibm_i( n, ieee, ibm)*   int n;*   int *ieee;*   int *ibm;* *  Convert IBM to IEEE short floating point:**   ibm_ieee_f( n, ibm, ieee)*   int n;*   char *ibm;*   float *ieee;* *  Convert IEEE to IBM floating point:**   ieee_ibm_f( n, ieee, ibm)*   int n;*   float *ieee;*   char *ibm;**---------------------------------------------------------------------*/void ibm_ieee_i( int n, char *ibm, char *ieee )/*        Convert from IBM to IEEE integer, possibly in-place*/#ifdef L_ENDIAN{  int j;  char temp;  /* Reverse byte order on little endian machines */  for (j=0; j<4*n; j+=4) {    temp=ibm[j];    ieee[j]=ibm[j+3];    ieee[j+3]=temp;    temp=ibm[j+1];    ieee[j+1]=ibm[j+2];    ieee[j+2]=temp;  }#else  {    int j;    /* Move words if not same location */    if (ibm != ieee)      for (j=0; j<n; j++)	ieee[j] = ibm[j];#endif /* L_ENDIAN */    return ;  }  /*********************************************************************/ void ieee_ibm_i( int n, char *ibm, char *ieee ) /*        Convert from IEEE to IBM integer, possibly in-place*/#ifdef L_ENDIAN  {    int j;    char temp;    /* Reverse byte order on little endian machines */    for (j=0; j<4*n; j+=4) {      temp=ieee[j];      ibm[j]=ieee[j+3];      ibm[j+3]=temp;      temp=ieee[j+1];      ibm[j+1]=ieee[j+2];      ibm[j+2]=temp;    }#else    {      int j;      /* Move words if not same location */      if (ibm != ieee)	for (j=0; j<n; j++)	  ibm[j] = ieee[j];#endif /* L_ENDIAN */      return ;    }    /*---------------------------------------------------------------------**  Convert from IBM short real to IEEE short real***  Bit formats for Big Endian processors (i.e. 68020, SPARC, RS6000):**              0         1        2        3         Byte Offset*          --------------------------------------*  IBM     !S! EXP   !   MH   !   MM   !   ML   !*          --------------------------------------*           0 1     7 8     15 16    23 24    31     bit number**              0         1        2        3         Byte Offset*          --------------------------------------*  IEEE    !S! EXP    !  MH   !   MM   !   ML   !*          --------------------------------------*           0 1      8 9    15 16    23 24    31     bit number***  Bit formats for Little Endian processors (i.e. Intel 80x86):**              3         2        1        0         byte offset*          --------------------------------------*  IBM     !   ML   !   MH   !   MH   !S!  EXP  !*          --------------------------------------*           31    24 23    16 15     8 7 6     0     bit number**              3         2        1        0         byte offset*          --------------------------------------*  IEEE    !S!  EXP  !!  MH   !   MM   !   ML   !*          --------------------------------------*          31 30    23 22   16 15     8 7      0     bit number***  ML, MM, and MH refer to the low, middle, and high order mantissa*  bytes.  S is the sign bit, EXP is the exponent.  Bits and bytes*  are numbered in order of increasing address in memory.  The fields*  are shown in the order that a Hex constant in C would be used as*  a mask for accessing bits.*** A floating point number in the IBM format is defined to be:**      (sign) 0.(significand) * 16**(exponent-64)** In the IEEE format, a floating point number is:**      (sign) 1.(significand) * 2**(exponent-127)** The differences are:**       1. IBM assumes a 0 to left of decimal point,*          IEEE assumes a 1 to left of decimal point.*          Since the IBM format has 1 more bit for the significand,*          they both have the same precision: 24 binary digits.**       2. The base for the exponent is 16 for IBM, 2 for IEEE**       3. The bias for the exponent is 64 for IBM, 127 for IEEE**       4. The exponent is 7 bits for IBM, 8 for IEEE. The exponent*          range is then -64 to +63 for IBM, -127 to +128 for IEEE.**       5. Since the IBM format has base 16, the decimal exponent*          range for IBM is about twice that for IEEE:*          IBM:  0.1H * 16**(-64)  to  0.FFFFFFH * 16**(+63)*            =   5.4 * 10**(-79)   to   7.2 * 10**(+75)*          IEEE: 1.0H * 2**(-127)  to  1.FFFFFFH * 2**(+128)*            =   5.9 * 10**(-39)   to   6.8 * 10**(+38)** To convert IBM to IEEE:**       1. Multiply IBM exponent by 4 to convert base from 16 to 2,*          subtract 129 to adjust for difference in bias (16*4-127).**       2. Shift the IBM significand left 1 bit and subtract 1 from*          the exponent. If the significand MSB is still 0, repeat.**       3. If the exponent overflows, set result to +-infinity. If*          it underflows, set to +-zero.**       4. Move the converted sign, significand, and exponent into*          the appropriate fields for the IEEE format.*** To convert IEEE to IBM:**       1. Get IEEE mantissa (bits 0-22). OR in a 1 in bit 23 to*          account for assumed leading '1'.**       2. Get IEEE exponent.  Add 1 to exponent to place the decimal*          point before the '1' in the mantissa.  Subtract IEEE bias*          of 127 to yield true base 2 exponent.**       3. Divide IEEE exponent by 4 to convert to base 16 exponent:*            0.X * 2**Y = 0.X * 16**(Y/4)*          Save remainder from division.  If remainder is not zero:*            0.X * 16**(I+1/4) = 2*(0.X) * 16**I = (1/8)0.X * 16**(I+1)*            0.X * 16**(I+2/4) = 4*(0.X) * 16**I = (1/4)0.X * 16**(I+1)*            0.X * 16**(I+3/4) = 8*(0.X) * 16**I = (1/2)0.X * 16**(I+1)*          I.E., add 1 to exponent, shift mantissa right by*          (4 - remainder).  Add IBM bias of 64 to exponent.**       4. Move the converted sign, significand, and exponent into*          the appropriate fields for the IBM format.***---------------------------------------------------------------------*/   void  ibm_ieee_f( int n, VAL *ibm, VAL *ieee )     {      int i,iret;      VAL tmp1,tmp2,temp;      int exp;      iret = 0;      for (i=0; i<n; i++) { 	/* Move IBM word to properly aligned temp location */	temp.c[0] = ibm[i].c[0];	temp.c[1] = ibm[i].c[1];	temp.c[2] = ibm[i].c[2];	temp.c[3] = ibm[i].c[3];	/* check for true zero */	if (temp.u == 0) {	  ieee[i].c[0] = ieee[i].c[1] = ieee[i].c[2] = 	    ieee[i].c[3] = '\0';	  continue;	}	/* extract mantissa */#ifdef L_ENDIAN	tmp1.c[0] = temp.c[3];	tmp1.c[1] = temp.c[2];	tmp1.c[2] = temp.c[1];	tmp1.c[3] = '\0';#else	tmp1.u = temp.u;	tmp1.c[0] = '\0';#endif	/* Extract exponent */	/* remove sign bit, multiply by 4, subtract bias difference */	exp = ((temp.c[0] & 0x7F) << 2 ) - 129;	/* Shift mantissa up 1 bit until there is a 1 in the MSB */	while ( (tmp1.u & 0x800000) == 0 ) {	  exp--;	  tmp1.u = tmp1.u << 1;	};	/* Discard MSB and decrement exponent 1 more */	tmp1.u = tmp1.u & 0x007FFFFF;	exp--;	/* Check for exponent overflow or underflow */	if (exp & 0xFF00) {	  if (exp < 0)	    /* Underflow */	    ieee[i].c[0] = ieee[i].c[1] = ieee[i].c[2] = 	      ieee[i].c[3] = '\0';	  else {	    /* Overflow */#ifdef L_ENDIAN	    ieee[i].c[3] = 0x7F;	    ieee[i].c[2] = 0x80;	    ieee[i].c[1] = 0x00;	    ieee[i].c[0] = 0x00;#else	    ieee[i].c[0] = 0x7F;	    ieee[i].c[1] = 0x80;	    ieee[i].c[2] = 0x00;	    ieee[i].c[3] = 0x00;#endif	  }	  iret = 1;	  continue;	}                        	/* Move exponent into proper field and set sign bit */	tmp2.u = 0;     #ifdef L_ENDIAN	tmp2.c[3] = (char)exp;	tmp2.u = tmp2.u >> 1;	if (temp.u & 0x00000080)	  tmp2.u = tmp2.u | 0x80000000;	else	  tmp2.u = tmp2.u & 0x7fffffff;#else	tmp2.c[0] = (char)exp;	tmp2.u = tmp2.u >> 1;	tmp2.u = tmp2.u | (temp.u & 0x80000000);#endif	/* Set output value */	temp.u = tmp1.u | tmp2.u;	ieee[i].c[0] = temp.c[0];	ieee[i].c[1] = temp.c[1];	ieee[i].c[2] = temp.c[2];	ieee[i].c[3] = temp.c[3];      }      return ;    }    /*********************************************************************/void    ieee_ibm_f( int n, VAL *ieee, VAL *ibm )     {      int i;      VAL temp,tmp1,tmp2;      int exp,rem;      for (i=0; i<n; i++) {	/* Move to properly aligned location */	temp.c[0] = ieee[i].c[0];	temp.c[1] = ieee[i].c[1];	temp.c[2] = ieee[i].c[2];	temp.c[3] = ieee[i].c[3];	/* check for true zero */	if (temp.u == 0) {	  ibm[i].c[0] = ibm[i].c[1] = ibm[i].c[2] = 	    ibm[i].c[3] = '\0';	  continue;	}	/* extract mantissa, OR in leading '1' */	tmp1.u = (temp.u & 0x007FFFFF) | 0x00800000;	/* Extract exponent */	/* remove sign bit, shift up one bit */	tmp2.u = (temp.u & 0x7F800000) << 1;    	/* Add 1 for mantissa shift, subtract 127 for IEEE bias */#ifdef L_ENDIAN	exp = (unsigned)tmp2.c[3] - 126;#else	exp = (unsigned)tmp2.c[0] - 126;#endif	/* Divide exponent by 4, save remainder, add IBM bias of 64 */	rem = exp & 0x03;	exp = (exp >> 2) + 64;	/* Normalize mantissa by shifting by (4-remainder) */	if (rem) {	  tmp1.u = tmp1.u >> (4-rem);	  exp = exp + 1;	}                        	/* Move exponent and mantissa bytes into IBM locations */#ifdef L_ENDIAN	tmp2.u = 0;     	tmp2.c[0] = (char)exp;	tmp2.c[1] = tmp1.c[2];	tmp2.c[2] = tmp1.c[1];	tmp2.c[3] = tmp1.c[0];	/* Set sign bit */	if (temp.u & 0x80000000) tmp2.u = tmp2.u | 0x00000080;#else	tmp2.u = tmp1.u;	tmp2.c[0] = (char)exp;	/* Set sign bit */	if (temp.u & 0x80000000) tmp2.u = tmp2.u | 0x80000000;#endif	/* Set output value */	ibm[i].c[0] = tmp2.c[0];	ibm[i].c[1] = tmp2.c[1];	ibm[i].c[2] = tmp2.c[2];	ibm[i].c[3] = tmp2.c[3];      }      return ;    }    /*********************************************************************//* Fortran interfaces */    void ibm2iei_( int *n, char *ibm, char *ieee )    {      ibm_ieee_i( *n, ibm, ieee );    }    void ie2ibmi_( int *n, char *ieee, char *ibm )    {      ieee_ibm_i( *n, ieee, ibm );    }    void ibm2ief_(int *n, char *ibm, char *ieee )    {      ibm_ieee_f( *n, (VAL *)ibm, (VAL *)ieee );    }    void ie2ibmf_( int *n, char *ieee, char *ibm )    {      ieee_ibm_f( *n, (VAL *)ieee, (VAL *)ibm );    }		void ibm_ieee_float(void *ibm, void *ieee, int n)	{		ibm_ieee_f( n, (VAL *)ibm, (VAL *)ieee );	}	void ieee_ibm_float(void *ieee, void *ibm, int n)	{		ieee_ibm_f( n, (VAL *)ieee, (VAL *)ibm );	}	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -