netmsgs/libnetmsgs/nmLibPack.c
int nmPackF64(double val, byte_t buf[], size_t bufSize, NMEndian_T eEndian)
{
  static size_t fvalLen = NMFVAL_LEN_F64;     // message field value length

  union ieee754_float   f;        // 4-byte floating-point number
  union ieee754_double  d;        // 8-byte floating-point number
  uint_t                uMSB;     // Most Signifcant Bytes
  uint_t                uLSB;     // Least Signifcant Bytes

  _NM_CHK_MEM(bufSize, fvalLen);

  // 8-byte double
  if( sizeof(double) == fvalLen )
  {
    d.d = val;
  }

  // 4-byte double
  else
  {
    _NM_CHK_ARCH(val, (size_t)NMFVAL_LEN_F32);

    f.f = (float)val;

    // special infinity cases
    if( ieee754_f32_is_inf(f) )
    {
      d = IEEE754_F64_Inf;
    }

    // special zero cases
    else if( ieee754_f32_is_zero(f) )
    {
      d = IEEE754_F64_Zero;
    }

    // special Not-a-Number case
    else if( ieee754_f32_is_nan(f) )
    {
      d = IEEE754_F64_NaN;
    }
    
    // "normal" floating-point numbers
    else
    {
      d.ieee.exponent   = (f.ieee.exponent  + (uint_t)IEEE754_DOUBLE_BIAS
                                            - (uint_t)IEEE754_FLOAT_BIAS)
                            & IEEE754_F64_EXPONENT_MASK;
      d.ieee.mantissa0  = ((uint_t)(f.ieee.mantissa 
                                  >> (uint_t)IEEE754_F32_F64_MANTISSA0_SHIFT))
                            & IEEE754_F64_MANTISSA0_MASK;
      d.ieee.mantissa1  = (((uint_t)(f.ieee.mantissa)) 
                                  & (uint_t)IEEE754_F32_F64_MANTISSA1_MASK)
                            << IEEE754_F32_F64_MANTISSA1_SHIFT;
    }

    // preserve the sign
    d.ieee.negative = f.ieee.negative;
  }

  //
  // Stuff the bits into two 4-byte unsigned integers.
  //
  uMSB  = (uint_t)((d.ieee.negative & IEEE754_F64_SIGN_MASK)
                        << IEEE754_F64_SIGN_SHIFT);
  uMSB |= (uint_t)((d.ieee.exponent & IEEE754_F64_EXPONENT_MASK)
                        << IEEE754_F64_EXPONENT_SHIFT);
  uMSB |= (uint_t)((d.ieee.mantissa0 & IEEE754_F64_MANTISSA0_MASK)
                        << IEEE754_F64_MANTISSA0_SHIFT);
  uLSB  = (uint_t)((d.ieee.mantissa1 & IEEE754_F64_MANTISSA1_MASK)
                        << IEEE754_F64_MANTISSA1_SHIFT);

  switch( eEndian )
  {
    case NMEndianLittle:
      PACK64LITTLE(uMSB, uLSB, buf);
      break;
    case NMEndianNative:
      PACK64NATIVE(uMSB, uLSB, buf);
      break;
    case NMEndianBig:
    default:
      PACK64BIG(uMSB, uLSB, buf);
      break;
  }

  return (int)fvalLen;
}
/*!
 * \brief Pack a 64-bit float into the message buffer.
 *
 * The IEEE 754 64-bit format is used with both the big and little endian byte
 * orders. If the machine architecture only supports 32-bit doubles, then a
 * conversion to 64-bit representation is performed first.
 *
 * \note
 *  <em>On some machines, while integers were represented in little-endian form,
 *  floating point numbers were represented in big-endian form. Because there
 *  are many floating point formats, and a lack of a standard <b>network</b>
 *  representation, no standard for transferring floating point values has been
 *  made</em> - Wikipedia.
 *
 *  \todo
 *  Detect non-IEEE 754 formats and convert to IEEE 754 prior to packing.
 *
 * \copydoc doc_params_pack_std
 * \copydoc doc_return_pack_std 
 */
\brief Pack a 64-bit float into the message buffer.
The IEEE 754 64-bit format is used with both the big and little endian byte
orders. If the machine architecture only supports 32-bit doubles, then a
conversion to 64-bit representation is performed first.

\note
On some machines, while integers were represented in little-endian form,
floating point numbers were represented in big-endian form. Because there
are many floating point formats, and a lack of a standard network
representation, no standard for transferring floating point values has been
made - Wikipedia.

\todo
Detect non-IEEE 754 formats and convert to IEEE 754 prior to packing.


\ brief Pack a 64 - bit float into the message buffer . The IEEE 754 64 - bit format is used with both the big and little endian byte orders . If the machine architecture only supports 32 - bit doubles then a conversion to 64 - bit representation is performed first . \ note On some machines while integers were represented in little - endian form floating point numbers were represented in big - endian form . Because there are many floating point formats and a lack of a standard network representation no standard for transferring floating point values has been made - Wikipedia . \ todo Detect non - IEEE 754 formats and convert to IEEE 754 prior to packing .
int nmPackF64(double val, byte_t buf[], size_t bufSize, NMEndian_T eEndian)
{
  static size_t fvalLen = NMFVAL_LEN_F64;     
  union ieee754_float   f;        
  union ieee754_double  d;        
  uint_t                uMSB;     
  uint_t                uLSB;     
  _NM_CHK_MEM(bufSize, fvalLen);
  if( sizeof(double) == fvalLen )
  {
    d.d = val;
  }
  else
  {
    _NM_CHK_ARCH(val, (size_t)NMFVAL_LEN_F32);
    f.f = (float)val;
    if( ieee754_f32_is_inf(f) )
    {
      d = IEEE754_F64_Inf;
    }
    else if( ieee754_f32_is_zero(f) )
    {
      d = IEEE754_F64_Zero;
    }
    else if( ieee754_f32_is_nan(f) )
    {
      d = IEEE754_F64_NaN;
    }
    else
    {
      d.ieee.exponent   = (f.ieee.exponent  + (uint_t)IEEE754_DOUBLE_BIAS
                                            - (uint_t)IEEE754_FLOAT_BIAS)
                            & IEEE754_F64_EXPONENT_MASK;
      d.ieee.mantissa0  = ((uint_t)(f.ieee.mantissa 
                                  >> (uint_t)IEEE754_F32_F64_MANTISSA0_SHIFT))
                            & IEEE754_F64_MANTISSA0_MASK;
      d.ieee.mantissa1  = (((uint_t)(f.ieee.mantissa)) 
                                  & (uint_t)IEEE754_F32_F64_MANTISSA1_MASK)
                            << IEEE754_F32_F64_MANTISSA1_SHIFT;
    }
    d.ieee.negative = f.ieee.negative;
  }
   Stuff the bits into two 4-byte unsigned integers.
  uMSB  = (uint_t)((d.ieee.negative & IEEE754_F64_SIGN_MASK)
                        << IEEE754_F64_SIGN_SHIFT);
  uMSB |= (uint_t)((d.ieee.exponent & IEEE754_F64_EXPONENT_MASK)
                        << IEEE754_F64_EXPONENT_SHIFT);
  uMSB |= (uint_t)((d.ieee.mantissa0 & IEEE754_F64_MANTISSA0_MASK)
                        << IEEE754_F64_MANTISSA0_SHIFT);
  uLSB  = (uint_t)((d.ieee.mantissa1 & IEEE754_F64_MANTISSA1_MASK)
                        << IEEE754_F64_MANTISSA1_SHIFT);
  switch( eEndian )
  {
    case NMEndianLittle:
      PACK64LITTLE(uMSB, uLSB, buf);
      break;
    case NMEndianNative:
      PACK64NATIVE(uMSB, uLSB, buf);
      break;
    case NMEndianBig:
    default:
      PACK64BIG(uMSB, uLSB, buf);
      break;
  }
  return (int)fvalLen;
}
int nmPackF64 ( double val , byte_t buf [ ] , size_t bufSize , NMEndian_T eEndian ) { static size_t fvalLen = NMFVAL_LEN_F64 ; union ieee754_float f ; union ieee754_double d ; uint_t uMSB ; uint_t uLSB ; _NM_CHK_MEM ( bufSize , fvalLen ) ; if ( sizeof ( double ) == fvalLen ) { d . d = val ; } else { _NM_CHK_ARCH ( val , ( size_t ) NMFVAL_LEN_F32 ) ; f . f = ( float ) val ; if ( ieee754_f32_is_inf ( f ) ) { d = IEEE754_F64_Inf ; } else if ( ieee754_f32_is_zero ( f ) ) { d = IEEE754_F64_Zero ; } else if ( ieee754_f32_is_nan ( f ) ) { d = IEEE754_F64_NaN ; } else { d . ieee . exponent = ( f . ieee . exponent + ( uint_t ) IEEE754_DOUBLE_BIAS - ( uint_t ) IEEE754_FLOAT_BIAS ) & IEEE754_F64_EXPONENT_MASK ; d . ieee . mantissa0 = ( ( uint_t ) ( f . ieee . mantissa >> ( uint_t ) IEEE754_F32_F64_MANTISSA0_SHIFT ) ) & IEEE754_F64_MANTISSA0_MASK ; d . ieee . mantissa1 = ( ( ( uint_t ) ( f . ieee . mantissa ) ) & ( uint_t ) IEEE754_F32_F64_MANTISSA1_MASK ) << IEEE754_F32_F64_MANTISSA1_SHIFT ; } d . ieee . negative = f . ieee . negative ; } uMSB = ( uint_t ) ( ( d . ieee . negative & IEEE754_F64_SIGN_MASK ) << IEEE754_F64_SIGN_SHIFT ) ; uMSB |= ( uint_t ) ( ( d . ieee . exponent & IEEE754_F64_EXPONENT_MASK ) << IEEE754_F64_EXPONENT_SHIFT ) ; uMSB |= ( uint_t ) ( ( d . ieee . mantissa0 & IEEE754_F64_MANTISSA0_MASK ) << IEEE754_F64_MANTISSA0_SHIFT ) ; uLSB = ( uint_t ) ( ( d . ieee . mantissa1 & IEEE754_F64_MANTISSA1_MASK ) << IEEE754_F64_MANTISSA1_SHIFT ) ; switch ( eEndian ) { case NMEndianLittle : PACK64LITTLE ( uMSB , uLSB , buf ) ; break ; case NMEndianNative : PACK64NATIVE ( uMSB , uLSB , buf ) ; break ; case NMEndianBig : default : PACK64BIG ( uMSB , uLSB , buf ) ; break ; } return ( int ) fvalLen ; }
\brief Pack a 64-bit float into the message buffer.
\ brief Pack a 64 - bit float into the message buffer .
// message field value length // 4-byte floating-point number // 8-byte floating-point number // Most Signifcant Bytes // Least Signifcant Bytes // 8-byte double // 4-byte double // special infinity cases // special zero cases // special Not-a-Number case // "normal" floating-point numbers // preserve the sign // // Stuff the bits into two 4-byte unsigned integers. //