From: merritt@climate.gsfc.nasa.gov (John H. Merritt)
Subject: Re: Binary File: SGI <-> IBM
Organization: Climate and Radiation Branch
Date: Thu, 13 Aug 1992 20:27:09 GMT

In article <1157@deere.com>, jrh@de.deere.com (John R. Howell) writes:
|> I have a binary file created with C fwrites and read with C freads.
|> 
|> If I create this on an SGI (IRIX) and read it with an IBM RS6000, I seem to
|> read everything ok, but my floating point numbers don't make sense. If
|> I go the other way (IBM -> SGI) a similar thing happens.
|> 
|> Apparently the integers are read correctly ...

On the IBM, you will find that floating point numbers are not stored base 2,
rather they are stored base 16.  Awh who cares, all you want are the routines
that can convert each 4 or 8 byte word.

Here are two routines to get you started.  The first converts a buffer
load of ibm r*4 variables to iris r*4 (bifloat) and the other (bireal8) handles
r*8.  It is up to you to call these routines at the appropriate time.

I hope you don't mind Leslie.

/*.............................................................*/
typedef STUFF char;
int bifloat(inn,out,num)
   STUFF *inn, *out;
   int num;
{
   /* translates real*4 */

   int i;
   long expont;

   for (i=0; i<num; i++)
   {

     out[3] = inn[3];   /* extract and copy mantissa */
     out[2] = inn[2];
     out[1] = inn[1];

     out[0] = inn[0] & 0x80;  /* put the sign in */

     expont = inn[0] & 127;  /* extract exponent */
     if (expont != 0)
     {

        expont -= 64; /* remove the offset of 64 */
        expont *= 4;  /* convert from 16-exp to 2-exp */

        /* find first non-zero byte in mantissa */
        if (out[1]) 
        {    /* first byte contains a bit--do nothing */
        }
        else if (out[2])
        {    /* second byte contains a bit--move up to first byte */
             out[1] = out[2];
             out[2] = out[3];
             out[3] = 0;
             expont -= 8;
        }
        else if (out[1])
        {    /* third byte contains a bit--move up to first byte */
             out[1] = out[3];
             out[2] = 0;
             out[3] = 0;
             expont -= 16;
        }
        else
        {    /* none of the bytes contains a bit--we have zero */
        }

        /* make sure that the highest bit in the leading byte of the 
           mantissa is set */
        if (out[1]) 
        {
           while (!(out[1] & 0x80))
           {
               out[1] = (out[1]<<1) | ((out[2]>>7)& 1);
               out[2] = (out[2]<<1) | ((out[3]>>7)& 1);
               out[3] = (out[3]<<1) ;
               expont -= 1;
           }

           /* Now hide the highest bit */
           out[1] = out[1] & 0x7f ;
           expont -= 1;
        }

        /* now convert the exponent to iris format */
        expont += 127;

        if ((expont == 0) && ((out[0] | out[1] | out[2] | out[3]) != 0))
        {
           fprintf(stderr," Illegal Floating point value in real conversion\n");
           return i+1;
        }
        else if (expont < 0)
        {
           fprintf(stderr," Floating point underflow in real conversion\n");
            out[3] = 0;
            out[2] = 0;
            out[1] = 0;
            out[0] = 0;
        }
        else if (expont > 255) 
        {
            fprintf(stderr," Floating point overflow in real conversion\n");
            return i+1;
        }
        else
        {  /* ok to convert */
            out[0] = out[0] | ((expont >> 1) & 0x7f);
            out[1] = out[1] | (expont << 7);
        }

     }
     else
     {
            out[3] = 0;
            out[2] = 0;
            out[1] = 0;
            out[0] = 0;
     } 

     inn += 4;
     out += 4;
   }

   return i;

}

/*.............................................................*/
int bireal8(inn,out,num)
   STUFF *inn, *out;
   int num;
{
   /* translates real*8 */
   STUFF syn1, syn2;
   long expont;
   int i;

   for (i=0; i<num; i++)
   {

     out[3] = inn[3];   /* extract and copy mantissa */
     out[2] = inn[2];
     out[1] = inn[1];
     out[5] = inn[5];
     out[4] = inn[4];
     out[7] = inn[7];
     out[6] = inn[6];

     out[0] = inn[0] & 0x80;  /* put the sign in */

     expont = inn[0] & 127;  /* extract exponent */
     if (expont != 0)
     {

        expont -= 64; /* remove the offset of 64 */
        expont *= 4;  /* convert from 16-exp to 2-exp */

        /* find first non-zero byte in mantissa */
        if (out[1]) 
        {    /* first byte contains a bit--do nothing */
        }
        else if (out[2])
        {    /* second byte contains a bit--move up to first byte */
             out[1] = out[2];
             out[2] = out[3];
             out[3] = out[4];
             out[4] = out[5];
             out[5] = out[6];
             out[6] = out[7];
             out[7] = 0;
             expont -= 8;
        }
        else if (out[3])
        {    /* third byte contains a bit--move up to first byte */
             out[1] = out[3];
             out[2] = out[4];
             out[3] = out[5];
             out[4] = out[6];
             out[5] = out[7];
             out[6] = 0;
             out[7] = 0;
             expont -= 16;
        }
        else if (out[4])
        {    /* fourth byte contains a bit--move up to first byte */
             out[1] = out[4];
             out[2] = out[5];
             out[3] = out[6];
             out[4] = out[7];
             out[5] = 0;
             out[6] = 0;
             out[7] = 0;
             expont -= 24;
        }
        else if (out[5])
        {    /* fifth byte contains a bit--move up to first byte */
             out[1] = out[5];
             out[2] = out[6];
             out[3] = out[7];
             out[4] = 0;
             out[5] = 0;
             out[6] = 0;
             out[7] = 0;
             expont -= 32;
        }
        else if (out[6])
        {    /* sixth byte contains a bit--move up to first byte */
             out[1] = out[6];
             out[2] = out[7];
             out[3] = 0;
             out[4] = 0;
             out[5] = 0;
             out[6] = 0;
             out[7] = 0;
             expont -= 40;
        }
        else if (out[7])
        {    /* seventh byte contains a bit--move up to first byte */
             out[1] = out[7];
             out[2] = 0;
             out[3] = 0;
             out[4] = 0;
             out[5] = 0;
             out[6] = 0;
             out[7] = 0;
             expont -= 48;
        }
        else
        {    /* none of the bytes contains a bit--we have zero */
        }

        /* make sure that the bit 4 in the leading byte of the 
           mantissa is set */
        if (out[1]) 
        {
           while (out[1] & 0xf0)  /* slide leading bits back */
           {
               out[7] = ((out[7]>>1) & 0x7f) | (out[6]<<7);
               out[6] = ((out[6]>>1) & 0x7f) | (out[5]<<7);
               out[5] = ((out[5]>>1) & 0x7f) | (out[4]<<7);
               out[4] = ((out[4]>>1) & 0x7f) | (out[3]<<7);
               out[3] = ((out[3]>>1) & 0x7f) | (out[2]<<7);
               out[2] = ((out[2]>>1) & 0x7f) | (out[1]<<7);
               out[1] = (out[1]>>1) & 0x7f;
               expont += 1;
           }
           while (!(out[1] & 0x10))   /* slide lower bits up */
           {
               out[1] = (out[1]<<1) | ((out[2]>>7)& 1);
               out[2] = (out[2]<<1) | ((out[3]>>7)& 1);
               out[3] = (out[3]<<1) | ((out[4]>>7)& 1);
               out[4] = (out[4]<<1) | ((out[5]>>7)& 1);
               out[5] = (out[5]<<1) | ((out[6]>>7)& 1);
               out[6] = (out[6]<<1) | ((out[7]>>7)& 1);
               out[7] = (out[7]<<1);
               expont -= 1;
           }

           /* Now hide the highest bit */
           out[1] = out[1] & 0x0f ;
           expont -= 4;
        }

        /* now convert the exponent to iris format */
        expont += 1023;

        if ((expont == 0) && ((out[0] | out[1] | out[2] | out[3] | out[4]
        | out[5] | out[6] | out[7]) != 0))
        {
          fprintf(stderr," Illegal Floating point value in double conversion\n");
          return i+1; 
        }
        else if (expont < 0)
        {
          fprintf(stderr," Floating point underflow in double conversion\n");
          out[7] = 0;
          out[6] = 0;
          out[5] = 0;
          out[4] = 0;
          out[3] = 0;
          out[2] = 0;
          out[1] = 0;
          out[0] = 0;
        }
        else if (expont > 4095) 
        {
          fprintf(stderr," Floating point overflow in double conversion\n");
          return i+1; 
        }
        else
        {  /* ok to convert */
           out[0] = out[0] | ((expont >> 4) & 0x7f);
           out[1] = out[1] | (expont << 4);
        }
     }
     else
     {
          out[7] = 0;
          out[6] = 0;
          out[5] = 0;
          out[4] = 0;
          out[3] = 0;
          out[2] = 0;
          out[1] = 0;
          out[0] = 0;
     } 

      inn += 8;
      out += 8;

   }

   return i;

}


-- 
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
John H. Merritt --> merritt@climate.gsfc.nasa.gov
"I am generally intolerant of ignorance,
but I have made an exception in your case."