Need to access MBF (Microsoft Binary Format) data

I need to access data from a 3rd party source but the numeric fields are stored in Microsoft Binary Format.  Does anyone have a suitable code snippet?  If not, I found the following code (think it is C / C++) that can hopefully be converted to Delphi.  I am using D1.

Not sure how much work is involved so will negotiate on points.

Adam

//
  // The following are implementations of Microsoft RTL functions
  // not include in the Borland RTL.
  //
  // Functions:
  //     _fmsbintoieee()
  //     _fieeetomsbin()
  //     _dmsbintoieee()
  //     _dieeetomsbin()
  //
  // These functions convert back and forth from Microsoft Binary
  // Format to IEEE floating point format.
  //
  // As with the Microsoft RTL functions,
  //
  // The argument srcX points to the value to be converted and the
  // result is stored at the location given at destX.
  //
  // These routines do not handle IEE NAN's and infinities.  IEEE
  // denormals are treated as 0's.
  //
  // Return:
  //
  // These functions return 0 if the conversion is successful and 1
  // if the conversion causes an overflow.
  //
  //
  //
  // Examples of the use of these functions can be found on-line as
  // MSBIN.ZIP.
  //
  //--------------------------------------------------------------------

  #include <string.h>        /* for strncpy  */

  int _fmsbintoieee(float *src4, float *dest4)
     {
     unsigned char *msbin = (unsigned char *)src4;
     unsigned char *ieee = (unsigned char *)dest4;
     unsigned char sign = 0x00;
     unsigned char ieee_exp = 0x00;
     int i;

     /* MS Binary Format                         */
     /* byte order =>    m3 | m2 | m1 | exponent */
     /* m1 is most significant byte => sbbb|bbbb */
     /* m3 is the least significant byte         */
     /*      m = mantissa byte                   */
     /*      s = sign bit                        */
     /*      b = bit                             */

     sign = msbin[2] & 0x80;      /* 1000|0000b  */

     /* IEEE Single Precision Float Format       */
     /*    m3        m2        m1     exponent   */
     /* mmmm|mmmm mmmm|mmmm emmm|mmmm seee|eeee  */
     /*          s = sign bit                    */
     /*          e = exponent bit                */
     /*          m = mantissa bit                */

     for (i=0; i<4; i++) ieee[i] = 0;

     /* any msbin w/ exponent of zero = zero */
     if (msbin[3] == 0) return 0;

     ieee[3] |= sign;

     /* MBF is bias 128 and IEEE is bias 127. ALSO, MBF places   */
     /* the decimal point before the assumed bit, while          */
     /* IEEE places the decimal point after the assumed bit.     */

     ieee_exp = msbin[3] - 2;    /* actually, msbin[3]-1-128+127 */

     /* the first 7 bits of the exponent in ieee[3] */
     ieee[3] |= ieee_exp >> 1;

     /* the one remaining bit in first bin of ieee[2] */
     ieee[2] |= ieee_exp << 7;

     /* 0111|1111b : mask out the msbin sign bit */
     ieee[2] |= msbin[2] & 0x7f;

     ieee[1] = msbin[1];
     ieee[0] = msbin[0];

     return 0;
     }


  int _fieeetomsbin(float *src4, float *dest4)
     {
     unsigned char *ieee = (unsigned char *)src4;
     unsigned char *msbin = (unsigned char *)dest4;
     unsigned char sign = 0x00;
     unsigned char msbin_exp = 0x00;
     int i;

     /* See _fmsbintoieee() for details of formats   */
     sign = ieee[3] & 0x80;
     msbin_exp |= ieee[3] << 1;
     msbin_exp |= ieee[2] >> 7;

     /* An ieee exponent of 0xfe overflows in MBF    */
     if (msbin_exp == 0xfe) return 1;

     msbin_exp += 2;     /* actually, -127 + 128 + 1 */

     for (i=0; i<4; i++) msbin[i] = 0;

     msbin[3] = msbin_exp;

     msbin[2] |= sign;
     msbin[2] |= ieee[2] & 0x7f;
     msbin[1] = ieee[1];
     msbin[0] = ieee[0];

     return 0;
     }


  int _dmsbintoieee(double *src8, double *dest8)
     {
     unsigned char msbin[8];
     unsigned char *ieee = (unsigned char *)dest8;
     unsigned char sign = 0x00;
     unsigned int ieee_exp = 0x0000;
     int i;

     /* A manipulatable copy of the msbin number     */
     strncpy((char *)msbin,(char *)src8,8);

   /* MS Binary Format                                           */
   /* byte order =>  m7 | m6 | m5 | m4 | m3 | m2 | m1 | exponent */
   /* m1 is most significant byte => smmm|mmmm                   */
   /* m7 is the least significant byte                           */
   /*      m = mantissa byte                                     */
   /*      s = sign bit                                          */
   /*      b = bit                                               */

     sign = msbin[6] & 0x80;      /* 1000|0000b  */


   /* IEEE Single Precision Float Format                         */
   /*  byte 8    byte 7    byte 6    byte 5    byte 4  and so on */
   /* seee|eeee eeee|mmmm mmmm|mmmm mmmm|mmmm mmmm|mmmm ...      */
   /*          s = sign bit                                      */
   /*          e = exponent bit                                  */
   /*          m = mantissa bit                                  */

     for (i=0; i<8; i++) ieee[i] = 0;

     /* any msbin w/ exponent of zero = zero */
     if (msbin[7] == 0) return 0;


     ieee[7] |= sign;

     /* MBF is bias 128 and IEEE is bias 1023. ALSO, MBF places  */
     /* the decimal point before the assumed bit, while          */
     /* IEEE places the decimal point after the assumed bit.     */

     ieee_exp = msbin[7] - 128 - 1 + 1023;

     /* First 4 bits of the msbin exponent   */
     /* go into the last 4 bits of ieee[7]   */
     ieee[7] |= ieee_exp >> 4;

     /* The last 4 bits of msbin exponent    */
     /* go into the first 4 bits of ieee[6]  */
     ieee[6] |= ieee_exp << 4;

     /* The msbin mantissa must be shifted to the right 1 bit.   */
     /* Remember that the msbin number has its bytes reversed.   */
     for (i=6; i>0; i--)
         {
         msbin[i] <<= 1;
         msbin[i] |= msbin[i-1] >> 7;
         }
     msbin[0] <<= 1;

     /* Now the mantissa is put into the ieee array starting in  */
     /* the middle of the second to last byte.                   */

     for (i=6; i>0; i--)
         {
         ieee[i] |= msbin[i] >> 4;
         ieee[i-1] |= msbin[i] << 4;
         }
     ieee[0] |= msbin[0] >> 4;

   /* IEEE has a half byte less for its mantissa.  If the msbin */
   /* number has anything in this last half byte, then there is */
   /* an overflow.                                              */
     if (msbin[0] & 0x0f)
         return 1;
     else
         return 0;
     }

  int _dieeetomsbin(double *src8, double *dest8)
     {
     unsigned char ieee[8];
     unsigned char *msbin = (unsigned char *)dest8;
     unsigned char sign = 0x00;
     unsigned char any_on = 0x00;
     unsigned int msbin_exp = 0x0000;
     int i;

     /* Make a clobberable copy of the source number */
     strncpy((char *)ieee,(char *)src8,8);

     for (i=0; i<8; i++) msbin[i] = 0;

     /* If all are zero in src8, the msbin should be zero */
     for (i=0; i<8; i++) any_on |= ieee[i];
     if (!any_on) return 0;

     sign = ieee[7] & 0x80;
     msbin[6] |= sign;
     msbin_exp = (unsigned)(ieee[7] & 0x7f) * 0x10;
     msbin_exp += ieee[6] >> 4;

     if (msbin_exp-0x3ff > 0x80) return 1;

     msbin[7] = msbin_exp - 0x3ff + 0x80 + 1;

     /* The ieee mantissa must be shifted up 3 bits */
     ieee[6] &= 0x0f; /* mask out the exponent in the second byte
     */
     for (i=6; i>0; i--)
         {
         msbin[i] |= ieee[i] << 3;
         msbin[i] |= ieee[i-1] >> 5;
         }

     msbin[0] |= ieee[0] << 3;

     return 0;
     }

asburgoyneAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

aikimarkCommented:
check-out project JEDI
DragonSlayerCommented:
Here you go :)

{====================================================================
MBF2IEEE
   Convert a Single number in MSBinary format to IEEE format.
====================================================================}
function MBF2IEEE(MBFVal: Single): Single;
type
   TInput = array[1..4] of byte;
var
   Output: array[1..4] of byte;
   Value: Single absolute Output;
//   Sign: byte;
   LSB: Byte;
begin
   try
      Output[4] := TInput(MBFVal)[4];
      { if value is non-zero, do some bit shuffling }
      if Output[4] > 2 then begin
         Output[3] := TInput(MBFVal)[3];
         Output[2] := TInput(MBFVal)[2];
         Output[1] := TInput(MBFVal)[1];
         Output[4] := Output[4] - $02;
         LSB := Output[4] and $01;
         Output[4] := (Output[4] shr 1) or (Output[3] and $80);
         if LSB = 0 then
            Output[3] := Output[3] and $7f
         else
            Output[3] := Output[3] or $80;
      { else return 0 }
      end else begin
         Output[1] := 0;
         Output[2] := 0;
         Output[3] := 0;
         Output[4] := 0;
      end;
      Result := Value;
   except
      Output[1] := 0;
      Output[2] := 0;
      Output[3] := 0;
      Output[4] := 0;
   end;
end;

{====================================================================
IEEE2MBF
   Convert a Single number in IEEE to MSBinary format.
====================================================================}
function IEEE2MBF(IEEEVal: Single): Single;
type
   TInput = array[1..4] of byte;
var
   Output: array[1..4] of byte;
   Value: Single absolute Output;
   Sign: byte;
   LSB: Byte;
begin
   try
      Output[4] := TInput(IEEEVal)[4];
      { if value is non-zero, do some bit shuffling }
      Output[3] := TInput(IEEEVal)[3];
      Output[2] := TInput(IEEEVal)[2];
      Output[1] := TInput(IEEEVal)[1];
      Sign := Output[4] and $80;
      LSB := Output[3] and $80;
      Output[4] := Output[4] shl 1;
      if LSB = $80 then
        Output[4] := Output[4] or $01
      else
         Output[4] := Output[4] or $00;
      Output[4] := Output[4] + $02;
      Output[3] := (Output[3] and $7f) or Sign;
      Result := Value;
   except
      Result := 0;
   end;
end;



Hope that helps!

DragonSlayer

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
asburgoyneAuthor Commented:
Thanks, DragonSlayer.  I actually got some code from the data provider that has done the job but thanks for your version.  How many points would you like?
DragonSlayerCommented:
asburgoyne, glad that you have solved the problem yourself... so it's actually up to you whether to provide me the points or not :)


DragonSlayer
asburgoyneAuthor Commented:
Thanks again, DragonSlayer
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.