Math Processor Unit Library

libmpu – library of arithmetic functions for integer, real, and complex numbers of increased digit capacity

16 Commits   0 Branches   2 Tags

/***************************************************************
  __MPU_REAL.C

       This file contains source code of functions for
       REAL arithmetic operations.

       PART OF : MPU - library .

       USAGE   : Internal only .

       NOTE    : NONE .

       Copyright (C) 2000 - 2024  by Andrew V.Kosteltsev.
       All Rights Reserved.
 ***************************************************************/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <errno.h>   /* errno(3)  */
#include <string.h>  /* strcpy(3) */
#include <strings.h> /* bzero(3)  */
#include <stdlib.h>

#include <libmpu.h>
#include <mpu-context.h>

#include <mpu-emutype.h>
#include <mpu-integer.h>
#include <mpu-real.h>

#include <mpu-char.h>
#include <mpu-symbols.h>

#include <mpu-math-errno.h>
#include <mpu-strerror.h>
#include <mpu-mtherr.h>


int internal_np( int nb )
/***************************************************************
 Description        : internal_np() возвращает количество слов
                                    размера EMUSHORT в internal
                                    e-type data struct.

 Concepts           :

 Use Global Variable:

 Use Functions      :

 Parameters         : int nb;  - количество бит в
                                 external e-type data
                                 struct.

 Return             : int rc;  - количество слов.
                      [rc = 0] - error.

 ***************************************************************/
{
  int rc = 0;

  switch( nb )
  {
    case NBR_32:
      rc = NPIR_32;
      break;
    case NBR_64:
      rc = NPIR_64;
      break;
    case NBR_128:
      rc = NPIR_128;
      break;

    case NBR_256:
      rc = NPIR_256;
      break;
    case NBR_512:
      rc = NPIR_512;
      break;
    case NBR_1024:
      rc = NPIR_1024;
      break;
    case NBR_2048:
      rc = NPIR_2048;
      break;
    case NBR_4096:
      rc = NPIR_4096;
      break;
    case NBR_8192:
      rc = NPIR_8192;
      break;
    case NBR_16384:
      rc = NPIR_16384;
      break;
    case NBR_32768:
      rc = NPIR_32768;
      break;
    case NBR_65536:
      rc = NPIR_65536;
      break;
    case NBR_131072:
      rc = NPIR_131072;
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      return( rc );
      break;
    }
  } /* End of switch( nb ) */

  return( rc );

} /* End of internal_np() */

int internal_ne( int nb )
/***************************************************************
 Description        : internal_ne() возвращает количество слов
                                    размера EMUSHORT в Exponent
                                    (internal e-type data
                                    struct).

 Concepts           :

 Use Global Variable:

 Use Functions      :

 Parameters         : int nb;  - количество бит в
                                 external e-type data
                                 struct.

 Return             : int rc;  - количество слов
                                 Exponent.
                      [rc = 0] - error.

 ***************************************************************/
{
  int rc = 0;

  switch( nb )
  {
    case NBR_32:
      rc = NPIE_32;
      break;
    case NBR_64:
      rc = NPIE_64;
      break;
    case NBR_128:
      rc = NPIE_128;
      break;

    case NBR_256:
      rc = NPIE_256;
      break;
    case NBR_512:
      rc = NPIE_512;
      break;
    case NBR_1024:
      rc = NPIE_1024;
      break;
    case NBR_2048:
      rc = NPIE_2048;
      break;
    case NBR_4096:
      rc = NPIE_4096;
      break;
    case NBR_8192:
      rc = NPIE_8192;
      break;
    case NBR_16384:
      rc = NPIE_16384;
      break;
    case NBR_32768:
      rc = NPIE_32768;
      break;
    case NBR_65536:
      rc = NPIE_65536;
      break;
    case NBR_131072:
      rc = NPIE_131072;
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      return( rc );
      break;
    }
  } /* End of switch( nb ) */

  return( rc );

} /* End of internal_ne() */

int internal_ns( int nb )
/***************************************************************
 Description        : internal_ns() возвращает количество слов
                                    размера EMUSHORT в
                                    Significand (internal e-type
                                    data struct).

 Concepts           :

 Use Global Variable:

 Use Functions      :

 Parameters         : int nb;  - количество бит в
                                 external e-type data
                                 struct.

 Return             : int rc;  - количество слов
                                 Significand.
                      [rc = 0] - error.

 ***************************************************************/
{
  int rc = 0;

  switch( nb )
  {
    case NBR_32:
      rc = NPIR_32 - 3 - NPIE_32;
      break;
    case NBR_64:
      rc = NPIR_64 - 3 - NPIE_64;
      break;
    case NBR_128:
      rc = NPIR_128 - 3 - NPIE_128;
      break;

    case NBR_256:
      rc = NPIR_256 - 3 - NPIE_256;
      break;
    case NBR_512:
      rc = NPIR_512 - 3 - NPIE_512;
      break;
    case NBR_1024:
      rc = NPIR_1024 - 3 - NPIE_1024;
      break;
    case NBR_2048:
      rc = NPIR_2048 - 3 - NPIE_2048;
      break;
    case NBR_4096:
      rc = NPIR_4096 - 3 - NPIE_4096;
      break;
    case NBR_8192:
      rc = NPIR_8192 - 3 - NPIE_8192;
      break;
    case NBR_16384:
      rc = NPIR_16384 - 3 - NPIE_16384;
      break;
    case NBR_32768:
      rc = NPIR_32768 - 3 - NPIE_32768;
      break;
    case NBR_65536:
      rc = NPIR_65536 - 3 - NPIE_65536;
      break;
    case NBR_131072:
      rc = NPIR_131072 - 3 - NPIE_131072;
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      return( rc );
      break;
    }
  } /* End of switch( nb ) */

  return( rc );

} /* End of internal_ns() */


void ei_cleaz( EMUSHORT *ei, int nb )
/***************************************************************

 Description        : ei_cleaz() Работает с
                                 internal e-type data struct.

 Concepts           : clear out exploded internal e-type real
                      number.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void]

 ***************************************************************/
{
  int  np;

  np = internal_np( nb );

  (void)memset( (void *)ei, 0, np * SIZE_OF_EMUSHORT );

} /* End of ei_cleaz() */

void ei_cleazs( EMUSHORT *ei, int nb )
/***************************************************************

 Description        : ei_cleazs() Работает с
                                  internal e-type data struct.

 Concepts           : clear out exploded internal e-type real
                      number, but don't touch the sign.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void]

 ***************************************************************/
{
  int  np;

  np = internal_np( nb ) - 1;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ++ei;
#endif

  (void)memset( (void *)ei, 0, np * SIZE_OF_EMUSHORT );

} /* End of ei_cleazs() */


#if MPU_WORD_ORDER_BIG_ENDIAN == 0
#include <r_const/ei_ind_emu32lsb.dfn>
#else
#include <r_const/ei_ind_emu32msb.dfn>
#endif

void ei_ind( EMUSHORT *ei, int nb )
/***************************************************************

 Description        : ei_ind() Работает с
                               internal e-type data struct.

 Concepts           : формирует `неопределенность' (- 1.IND)

                      Sign  Exp  1. Significand
                      ==== ===== == ===========
                         1 1...1 1  10.......00,

                      которое не равно nan_max, nan_min и nan.

 Use Global Variable:

 Use Functions      :
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                     data struct.

 Return             : [void]

 ***************************************************************/
{
  size_t nbytes = internal_np( nb ) * SIZE_OF_EMUSHORT;

  switch( nb )
  {
    case NBR_32:
    case NBR_64:
    case NBR_128:
      (void)memcpy( (void *)ei, (void *)&_ei_ind_128_[0],    nbytes );
      break;
    case NBR_256:
      (void)memcpy( (void *)ei, (void *)&_ei_ind_256_[0],    nbytes );
      break;
    case NBR_512:
      (void)memcpy( (void *)ei, (void *)&_ei_ind_512_[0],    nbytes );
      break;
    case NBR_1024:
      (void)memcpy( (void *)ei, (void *)&_ei_ind_1024_[0],   nbytes );
      break;
    case NBR_2048:
      (void)memcpy( (void *)ei, (void *)&_ei_ind_2048_[0],   nbytes );
      break;
    case NBR_4096:
      (void)memcpy( (void *)ei, (void *)&_ei_ind_4096_[0],   nbytes );
      break;
    case NBR_8192:
      (void)memcpy( (void *)ei, (void *)&_ei_ind_8192_[0],   nbytes );
      break;
    case NBR_16384:
      (void)memcpy( (void *)ei, (void *)&_ei_ind_16384_[0],  nbytes );
      break;
    case NBR_32768:
      (void)memcpy( (void *)ei, (void *)&_ei_ind_32768_[0],  nbytes );
      break;
    case NBR_65536:
      (void)memcpy( (void *)ei, (void *)&_ei_ind_65536_[0],  nbytes );
      break;
    case NBR_131072:
      (void)memcpy( (void *)ei, (void *)&_ei_ind_131072_[0], nbytes );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

} /* End of ei_ind() */

int ei_isind( EMUSHORT *ei, int nb )
/***************************************************************

 Description        : ei_isind() Работает с
                                 internal e-type data struct.

 Concepts           : проверка на `неопределенность' (- 1.IND)

                      Sign  Exp  1. Significand
                      ==== ===== == ===========
                         1 1...1 1  10.......00,

                      которая не равна nan_max, nan_min и nan.

 Use Global Variable:

 Use Functions      :
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( `неопределенность' ) [rc = 1];
                      else                     [rc = 0];

 ***************************************************************/
{
  int ie, ne, is, ns;
  int rc = 0; /* Return Code */

  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*************************************************************
    NOTE:
    ====
      Compare 'Sign...Exp' and 'Significand'; skip lgw and hgw.
   */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ie = 0; is = ne + 2;
#else
  ie = ns + 2; is = 1;
#endif

  ++ne;

  ne *= SIZE_OF_EMUSHORT;
  ns *= SIZE_OF_EMUSHORT;

  switch( nb )
  {
    case NBR_32:
    case NBR_64:
    case NBR_128:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_ind_128_[0][ie],    (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_ind_128_[0][is],    (size_t)ns )
        ) rc = 1;
      break;
    case NBR_256:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_ind_256_[0][ie],    (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_ind_256_[0][is],    (size_t)ns )
        ) rc = 1;
      break;
    case NBR_512:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_ind_512_[0][ie],    (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_ind_512_[0][is],    (size_t)ns )
        ) rc = 1;
      break;
    case NBR_1024:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_ind_1024_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_ind_1024_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_2048:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_ind_2048_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_ind_2048_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_4096:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_ind_4096_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_ind_4096_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_8192:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_ind_8192_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_ind_8192_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_16384:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_ind_16384_[0][ie],  (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_ind_16384_[0][is],  (size_t)ns )
        ) rc = 1;
      break;
    case NBR_32768:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_ind_32768_[0][ie],  (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_ind_32768_[0][is],  (size_t)ns )
        ) rc = 1;
      break;
    case NBR_65536:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_ind_65536_[0][ie],  (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_ind_65536_[0][is],  (size_t)ns )
        ) rc = 1;
      break;
    case NBR_131072:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_ind_131072_[0][ie], (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_ind_131072_[0][is], (size_t)ns )
        ) rc = 1;
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

  return rc;

} /* End of ei_isind() */


#if MPU_WORD_ORDER_BIG_ENDIAN == 0
#include <r_const/e_ind_emu32lsb.dfn>
#else
#include <r_const/e_ind_emu32msb.dfn>
#endif

void e_ind( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_ind() Работает с
                              external e-type data struct.

 Concepts           : формирует `неопределенность' (- 1.IND)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         1 1...1 10.......00,

                      которое не равно nan_max, nan_min и nan.

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void];

 ***************************************************************/
{
  size_t np = nb / BITS_PER_BYTE_T; /* in Bytes */
  /*************************************************************
    NOTE:
    ====
          Здесь работа идет словами EMUSHORT (согласно
          определениям из файлов e_ind_emu32*sb.dfn) и,
          следовательно, на данный момент подразумевается,
          что размер EMUSHORT равен 4 байта (32 bits).

          Если BITS_PER_EMUSHORT > 32, то надо использовать
          прямое присваивание значений, например:

            __mpu_uint32_t *e = (__mpu_uint32_t *)ee;
            *e = 0xffc00000;

          не забывая об очередности LITTLE/BIG endian.

   *************************************************************/
  switch( nb )
  {
    case NBR_32:
      (void)memcpy( (void *)ee, (void *)&_e_ind_32_[0],     np );
      break;
    case NBR_64:
      (void)memcpy( (void *)ee, (void *)&_e_ind_64_[0],     np );
      break;
    case NBR_128:
      (void)memcpy( (void *)ee, (void *)&_e_ind_128_[0],    np );
      break;
    case NBR_256:
      (void)memcpy( (void *)ee, (void *)&_e_ind_256_[0],    np );
      break;
    case NBR_512:
      (void)memcpy( (void *)ee, (void *)&_e_ind_512_[0],    np );
      break;
    case NBR_1024:
      (void)memcpy( (void *)ee, (void *)&_e_ind_1024_[0],   np );
      break;
    case NBR_2048:
      (void)memcpy( (void *)ee, (void *)&_e_ind_2048_[0],   np );
      break;
    case NBR_4096:
      (void)memcpy( (void *)ee, (void *)&_e_ind_4096_[0],   np );
      break;
    case NBR_8192:
      (void)memcpy( (void *)ee, (void *)&_e_ind_8192_[0],   np );
      break;
    case NBR_16384:
      (void)memcpy( (void *)ee, (void *)&_e_ind_16384_[0],  np );
      break;
    case NBR_32768:
      (void)memcpy( (void *)ee, (void *)&_e_ind_32768_[0],  np );
      break;
    case NBR_65536:
      (void)memcpy( (void *)ee, (void *)&_e_ind_65536_[0],  np );
      break;
    case NBR_131072:
      (void)memcpy( (void *)ee, (void *)&_e_ind_131072_[0], np );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

} /* End of e_ind() */

int e_isind( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isind() Работает с
                                external e-type data struct.

 Concepts           : проверка на `неопределенность' (- 1.IND)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         1 1...1 10.......00,

                      которое не равно nan_max, nan_min и nan.

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( `неопределенность' ) [rc = 1];
                      else                     [rc = 0];

 ***************************************************************/
{
  int    rc = 0;                    /* Return Code */
  size_t np = nb / BITS_PER_BYTE_T; /* in Bytes */

  switch( nb )
  {
    case NBR_32:
      if( !memcmp( (void *)ee, (void *)&_e_ind_32_[0],     np ) ) rc = 1;
      break;
    case NBR_64:
      if( !memcmp( (void *)ee, (void *)&_e_ind_64_[0],     np ) ) rc = 1;
      break;
    case NBR_128:
      if( !memcmp( (void *)ee, (void *)&_e_ind_128_[0],    np ) ) rc = 1;
      break;
    case NBR_256:
      if( !memcmp( (void *)ee, (void *)&_e_ind_256_[0],    np ) ) rc = 1;
      break;
    case NBR_512:
      if( !memcmp( (void *)ee, (void *)&_e_ind_512_[0],    np ) ) rc = 1;
      break;
    case NBR_1024:
      if( !memcmp( (void *)ee, (void *)&_e_ind_1024_[0],   np ) ) rc = 1;
      break;
    case NBR_2048:
      if( !memcmp( (void *)ee, (void *)&_e_ind_2048_[0],   np ) ) rc = 1;
      break;
    case NBR_4096:
      if( !memcmp( (void *)ee, (void *)&_e_ind_4096_[0],   np ) ) rc = 1;
      break;
    case NBR_8192:
      if( !memcmp( (void *)ee, (void *)&_e_ind_8192_[0],   np ) ) rc = 1;
      break;
    case NBR_16384:
      if( !memcmp( (void *)ee, (void *)&_e_ind_16384_[0],  np ) ) rc = 1;
      break;
    case NBR_32768:
      if( !memcmp( (void *)ee, (void *)&_e_ind_32768_[0],  np ) ) rc = 1;
      break;
    case NBR_65536:
      if( !memcmp( (void *)ee, (void *)&_e_ind_65536_[0],  np ) ) rc = 1;
      break;
    case NBR_131072:
      if( !memcmp( (void *)ee, (void *)&_e_ind_131072_[0], np ) ) rc = 1;
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

  return rc;

} /* End of e_isind() */


#if MPU_WORD_ORDER_BIG_ENDIAN == 0
#include <r_const/ei_nan_emu32lsb.dfn>
#else
#include <r_const/ei_nan_emu32msb.dfn>
#endif


void ei_nan( EMUSHORT *ei, unsigned sign, int nb )
/***************************************************************

 Description        : ei_nan() Работает с
                               internal e-type data struct.

 Concepts           : формирует `не число' (+/- 1.NAN)

                      Sign  Exp  1. Significand
                      ==== ===== == ===========
                         S 1...1 1  10.......01,

                      которое не равно nan_max, nan_min и ind.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ei;      - указатель на
                                           internal e-type
                                           data struct;
                      unsigned int sign; - знак формируемого
                                           числа;
                      int nb;            - количество бит в
                                           external e-type
                                           data struct.

 Return             : [void]

 ***************************************************************/
{
  int    sn = 0;
  size_t np = internal_np( nb ) * SIZE_OF_EMUSHORT;

  if( sign ) sn = 1;

  switch( nb )
  {
    case NBR_32:
    case NBR_64:
    case NBR_128:
      (void)memcpy( (void *)ei, (void *)&_ei_nan_128_[sn][0],    np );
      break;
    case NBR_256:
      (void)memcpy( (void *)ei, (void *)&_ei_nan_256_[sn][0],    np );
      break;
    case NBR_512:
      (void)memcpy( (void *)ei, (void *)&_ei_nan_512_[sn][0],    np );
      break;
    case NBR_1024:
      (void)memcpy( (void *)ei, (void *)&_ei_nan_1024_[sn][0],   np );
      break;
    case NBR_2048:
      (void)memcpy( (void *)ei, (void *)&_ei_nan_2048_[sn][0],   np );
      break;
    case NBR_4096:
      (void)memcpy( (void *)ei, (void *)&_ei_nan_4096_[sn][0],   np );
      break;
    case NBR_8192:
      (void)memcpy( (void *)ei, (void *)&_ei_nan_8192_[sn][0],   np );
      break;
    case NBR_16384:
      (void)memcpy( (void *)ei, (void *)&_ei_nan_16384_[sn][0],  np );
      break;
    case NBR_32768:
      (void)memcpy( (void *)ei, (void *)&_ei_nan_32768_[sn][0],  np );
      break;
    case NBR_65536:
      (void)memcpy( (void *)ei, (void *)&_ei_nan_65536_[sn][0],  np );
      break;
    case NBR_131072:
      (void)memcpy( (void *)ei, (void *)&_ei_nan_131072_[sn][0], np );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

} /* End of ei_nan() */

int ei_isnans( EMUSHORT *ei, int nb )
/***************************************************************

 Description        : ei_isnans() Работает с
                                  internal e-type data struct.

 Concepts           : проверка на `не число' (+/- 1.NAN)

                      Sign  Exp  1. Significand
                      ==== ===== == ===========
                         S 1...1 1  00.......01, min
                         + 1...1 1  10.......00, (-ind)
                         S 1...1 1  10.......01, 
                         S 1...1 1  11.......11, max

                      которое не равно           ind.

 Use Global Variable:

 Use Functions      :
                      ei_isind( ei, nb );         | this file
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( любое `не число' кроме `ind') [rc = 1];
                      else                              [rc = 0];

 ***************************************************************/
{
  int i, ne, ns;

  if( ei_isind( ei, nb ) ) return( 0 );

  ne = internal_ne( nb );
  ns = internal_ns( nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  ei = ei + ne + ns + 1;               /* skip Sign */
#else
  ei++;
#endif

  /* test ALL NaNs                                  */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* hight part of Exponent                         */
  if( (*ei++ & HIGHT_EXP) != HIGHT_EXP ) return( 0 );
  /* low parts of Exponent (if is present)          */
  for( i = 1; i < ne; i++ )
  {
    if( *ei++ != MASK_ALL_BITS ) return( 0 );
  }
  ei++;                             /* skip the hgw */
  /* hight part of Significand (без неявной 1.0)    */
  if( *ei++ & HIGHT_EXP ) return( 1 );
  /* low parts of Significand (if is present)       */
  for( i = 1; i < ns; i++ ) if( *ei++ ) return( 1 );
#else
  /* hight part of Exponent                         */
  if( (*ei-- & HIGHT_EXP) != HIGHT_EXP ) return( 0 );
  /* low parts of Exponent (if is present)          */
  for( i = 1; i < ne; i++ )
  {
    if( *ei-- != MASK_ALL_BITS ) return( 0 );
  }
  ei--;                             /* skip the hgw */
  /* hight part of Significand (без неявной 1.0)    */
  if( *ei-- & HIGHT_EXP ) return( 1 );
  /* low parts of Significand (if is present)       */
  for( i = 1; i < ns; i++ ) if( *ei-- ) return( 1 );
#endif
                                       /* ei -> lgw */
   return( 0 );

} /* End of ei_isnans() */


#if MPU_WORD_ORDER_BIG_ENDIAN == 0
#include <r_const/e_nan_emu32lsb.dfn>
#else
#include <r_const/e_nan_emu32msb.dfn>
#endif

void e_nan( EMUSHORT *ee, unsigned sign, int nb )
/***************************************************************

 Description        : e_ind() Работает с
                              external e-type data struct.

 Concepts           : формирует `не число' (+/- 1.NAN)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 10.......01,

                      которое не равно nan_max, nan_min и ind.

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee;      - указатель на
                                           external e-type
                                           data struct;
                      unsigned int sign; - знак формируемого
                                           числа;
                      int nb;            - количество бит в
                                           external e-type
                                           data struct.

 Return             : [void];

 ***************************************************************/
{
  int    sn = 0;
  size_t np = nb / BITS_PER_BYTE_T; /* in Bytes */

  if( sign ) sn = 1;

  switch( nb )
  {
    case NBR_32:
      (void)memcpy( (void *)ee, (void *)&_e_nan_32_[sn][0],     np );
      break;
    case NBR_64:
      (void)memcpy( (void *)ee, (void *)&_e_nan_64_[sn][0],     np );
      break;
    case NBR_128:
      (void)memcpy( (void *)ee, (void *)&_e_nan_128_[sn][0],    np );
      break;
    case NBR_256:
      (void)memcpy( (void *)ee, (void *)&_e_nan_256_[sn][0],    np );
      break;
    case NBR_512:
      (void)memcpy( (void *)ee, (void *)&_e_nan_512_[sn][0],    np );
      break;
    case NBR_1024:
      (void)memcpy( (void *)ee, (void *)&_e_nan_1024_[sn][0],   np );
      break;
    case NBR_2048:
      (void)memcpy( (void *)ee, (void *)&_e_nan_2048_[sn][0],   np );
      break;
    case NBR_4096:
      (void)memcpy( (void *)ee, (void *)&_e_nan_4096_[sn][0],   np );
      break;
    case NBR_8192:
      (void)memcpy( (void *)ee, (void *)&_e_nan_8192_[sn][0],   np );
      break;
    case NBR_16384:
      (void)memcpy( (void *)ee, (void *)&_e_nan_16384_[sn][0],  np );
      break;
    case NBR_32768:
      (void)memcpy( (void *)ee, (void *)&_e_nan_32768_[sn][0],  np );
      break;
    case NBR_65536:
      (void)memcpy( (void *)ee, (void *)&_e_nan_65536_[sn][0],  np );
      break;
    case NBR_131072:
      (void)memcpy( (void *)ee, (void *)&_e_nan_131072_[sn][0], np );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

} /* End of e_nan() */

static int e_isnans_32( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isnans_32() Работает с
                                    external e-type data struct.

 Concepts           : проверка на `не число' (+/- 1.NAN)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 00.......01, min
                         + 1...1 10.......00, (-ind)
                         S 1...1 10.......01, 
                         S 1...1 11.......11, max

                      которое не равно           ind.

 Use Global Variable:

 Use Functions      :
                      e_isind( ee, nb );          | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( любое `не число' кроме `ind') [rc = 1];
                      else                              [rc = 0];

 ***************************************************************/
{
  __mpu_uint16_t *e;
  int             rc = 1, rc1 = 0; /* Return Code */

  if( nb != NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return( rc1 );
  }

  if( e_isind( ee, nb ) ) return( rc1 );

  e = (__mpu_uint16_t *)ee;

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  e++; /* high part of real32 data struct */
#endif

  if( (*e & 0x7f80) == 0x7f80 ) rc &= 1;
  else                          rc &= 0;

  if( rc )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    if( ((*e & 0x7f) != 0) || (*(e + 1) != 0) )
#else
    if( ((*e & 0x7f) != 0) || (*(e - 1) != 0) )
#endif
      rc1 |= 1;

    return( rc1 );
  }
  else
  {
    return( rc1 );
  }

} /* End of e_isnans_32() */

static int e_isnans_64( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isnans_64() Работает с
                                    external e-type data struct.

 Concepts           : проверка на `не число' (+/- 1.NAN)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 00.......01, min
                         + 1...1 10.......00, (-ind)
                         S 1...1 10.......01, 
                         S 1...1 11.......11, max

                      которое не равно           ind.

 Use Global Variable:

 Use Functions      :
                      e_isind( ee, nb );          | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( любое `не число' кроме `ind') [rc = 1];
                      else                              [rc = 0];

 ***************************************************************/
{
  __mpu_uint32_t *e;
  int             rc = 1, rc1 = 0; /* Return Code */

  if( nb != NBR_64 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return( rc1 );
  }

  if( e_isind( ee, nb ) ) return( rc1 );

  e = (__mpu_uint32_t *)ee;

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  e++; /* high part of real32 data struct */
#endif

  if( (*e & 0x7ff00000) == 0x7ff00000 ) rc &= 1;
  else                                  rc &= 0;

  if( rc )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    if( ((*e & 0xfffff) != 0) || (*(e + 1) != 0) )
#else
    if( ((*e & 0xfffff) != 0) || (*(e - 1) != 0) )
#endif
      rc1 |= 1;

    return( rc1 );
  }
  else
  {
    return( rc1 );
  }

} /* End of e_isnans_64() */

static int e_isnans_np( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isnans_np() Работает с
                                    external e-type data struct.

 Concepts           : проверка на `не число' (+/- 1.NAN)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 00.......01, min
                         + 1...1 10.......00, (-ind)
                         S 1...1 10.......01, 
                         S 1...1 11.......11, max

                      которое не равно           ind.

 Use Global Variable:

 Use Functions      :
                      e_isind( ee, nb );          | this file
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( любое `не число' кроме `ind' ) [rc = 1];
                      else                               [rc = 0];

 ***************************************************************/
{
  int i, ne, ns;

  if( e_isind( ee, nb ) ) return( 0 );

  ne = internal_ne( nb );
  ns = internal_ns( nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  ee = ee + ne + ns - 1;                    /* Sign */
#endif

  /* test ALL NaNs                                  */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* hight part of Exponent (skip Sign)             */
  if( (*ee++ & HIGHT_EXP) != HIGHT_EXP ) return( 0 );
  /* low parts of Exponent (if is present)          */
  for( i = 1; i < ne; i++ )
  {
    if( *ee++ != MASK_ALL_BITS ) return( 0 );
  }
  /* all parts of Significand (if is present)       */
  for( i = 0; i < ns; i++ ) if( *ee++ ) return( 1 );
#else
  /* hight part of Exponent (skip Sign)             */
  if( (*ee-- & HIGHT_EXP) != HIGHT_EXP ) return( 0 );
  /* low parts of Exponent (if is present)          */
  for( i = 1; i < ne; i++ )
  {
    if( *ee-- != MASK_ALL_BITS ) return( 0 );
  }
  /* all parts of Significand (if is present)       */
  for( i = 0; i < ns; i++ ) if( *ee-- ) return( 1 );
#endif

  return( 0 );

} /* End of e_isnans_np() */

int e_isnans( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isnans() Работает с
                                 external e-type data struct.

 Concepts           : проверка на `не число' (+/- 1.NAN)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 00.......01, min
                         + 1...1 10.......00, (-ind)
                         S 1...1 10.......01, 
                         S 1...1 11.......11, max

                      которое не равно           ind.

 Use Global Variable:

 Use Functions      :
                      e_isnans_32();              | this file
                      e_isnans_64();              | this file
                      e_isnans_np();              | this file

 Parameters         : unsigned EMUSHORT *ee; - указатель на
                                               external e-type
                                               data struct;
                      unsigned int nb;       - количество бит в
                                               external e-type
                                               data struct.

 Return             : int rc;
                      if( любое `не число' кроме `ind' ) [rc = 1];
                      else                               [rc = 0];

 ***************************************************************/
{
  int rc = 0; /* Return Code */

  switch( nb )
  {
    case NBR_32    :
      rc = e_isnans_32( ee, nb );
      break;
    case NBR_64    :
      rc = e_isnans_64( ee, nb );
      break;
    case NBR_128   :
    case NBR_256   :
    case NBR_512   :
    case NBR_1024  :
    case NBR_2048  :
    case NBR_4096  :
    case NBR_8192  :
    case NBR_16384 :
    case NBR_32768 :
    case NBR_65536 :
    case NBR_131072:
      rc = e_isnans_np( ee, nb );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      return( rc );
      break;
    }
  } /* End of switch( nb ) */

  return( rc );

} /* End of e_isnans() */


#if MPU_WORD_ORDER_BIG_ENDIAN == 0
#include <r_const/ei_nanmax_emu32lsb.dfn>
#else
#include <r_const/ei_nanmax_emu32msb.dfn>
#endif

void ei_nanmax( EMUSHORT *ei, unsigned sign, int nb )
/***************************************************************

 Description        : ei_nanmax() Работает с
                                  internal e-type data struct.

 Concepts           : формирует максимальное `не число'
                      (+/- 1.NAN)

                      Sign  Exp  1. Significand
                      ==== ===== == ===========
                         S 1...1 1  11.......11,

                      которое не равно nan_min и ind.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ei;      - указатель на
                                           internal e-type
                                           data struct;
                      unsigned int sign; - знак формируемого
                                           числа;
                      int nb;            - количество бит в
                                           external e-type
                                           data struct.

 Return             : [void]

 ***************************************************************/
{
  int    sn = 0;
  size_t np = internal_np( nb ) * SIZE_OF_EMUSHORT;

  if( sign ) sn = 1;

  switch( nb )
  {
    case NBR_32:
    case NBR_64:
    case NBR_128:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmax_128_[sn][0],    np );
      break;
    case NBR_256:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmax_256_[sn][0],    np );
      break;
    case NBR_512:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmax_512_[sn][0],    np );
      break;
    case NBR_1024:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmax_1024_[sn][0],   np );
      break;
    case NBR_2048:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmax_2048_[sn][0],   np );
      break;
    case NBR_4096:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmax_4096_[sn][0],   np );
      break;
    case NBR_8192:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmax_8192_[sn][0],   np );
      break;
    case NBR_16384:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmax_16384_[sn][0],  np );
      break;
    case NBR_32768:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmax_32768_[sn][0],  np );
      break;
    case NBR_65536:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmax_65536_[sn][0],  np );
      break;
    case NBR_131072:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmax_131072_[sn][0], np );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

} /* End of ei_nanmax() */

int ei_isnanmax( EMUSHORT *ei, int nb )
/***************************************************************

 Description        : ei_isnanmax() Работает с
                                    internal e-type data struct.

 Concepts           : проверка на максимальное `не число'
                      (+/- 1.NAN)

                      Sign  Exp  1. Significand
                      ==== ===== == ===========
                         S 1...1 1  11.......11,

                      которое не равно nan_min и ind.

 Use Global Variable:

 Use Functions      :
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( max `не число' ) [rc = 1];
                      else                 [rc = 0];

 ***************************************************************/
{
  int ie, ne, is, ns;
  int rc = 0; /* Return Code */

  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*************************************************************
    NOTE:
    ====
      Compare 'Exp' and 'Significand'; skip Sign, lgw and hgw.
   */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ie = 1; is = ne + 2;
#else
  ie = ns + 2; is = 1;
#endif

  ne *= SIZE_OF_EMUSHORT;
  ns *= SIZE_OF_EMUSHORT;

  switch( nb )
  {
    case NBR_32:
    case NBR_64:
    case NBR_128:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmax_128_[0][ie],    (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmax_128_[0][is],    (size_t)ns )
        ) rc = 1;
      break;
    case NBR_256:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmax_256_[0][ie],    (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmax_256_[0][is],    (size_t)ns )
        ) rc = 1;
      break;
    case NBR_512:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmax_512_[0][ie],    (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmax_512_[0][is],    (size_t)ns )
        ) rc = 1;
      break;
    case NBR_1024:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmax_1024_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmax_1024_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_2048:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmax_2048_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmax_2048_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_4096:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmax_4096_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmax_4096_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_8192:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmax_8192_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmax_8192_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_16384:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmax_16384_[0][ie],  (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmax_16384_[0][is],  (size_t)ns )
        ) rc = 1;
      break;
    case NBR_32768:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmax_32768_[0][ie],  (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmax_32768_[0][is],  (size_t)ns )
        ) rc = 1;
      break;
    case NBR_65536:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmax_65536_[0][ie],  (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmax_65536_[0][is],  (size_t)ns )
        ) rc = 1;
      break;
    case NBR_131072:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmax_131072_[0][ie], (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmax_131072_[0][is], (size_t)ns )
        ) rc = 1;
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

  return rc;

} /* End of ei_isnanmax() */


#if MPU_WORD_ORDER_BIG_ENDIAN == 0
#include <r_const/e_nanmax_emu32lsb.dfn>
#else
#include <r_const/e_nanmax_emu32msb.dfn>
#endif

void e_nanmax( EMUSHORT *ee, unsigned sign, int nb )
/***************************************************************

 Description        : e_nanmax() Работает с
                                 external e-type data struct.

 Concepts           : формирует максимальное `не число'
                      (+/- 1.NAN)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 11.......11,

                      которое не равно nan_min и ind.

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee;      - указатель на
                                           external e-type
                                           data struct;
                      unsigned int sign; - знак формируемого
                                           числа;
                      int nb;            - количество бит в
                                           external e-type
                                           data struct.

 Return             : [void];

 ***************************************************************/
{
  int    sn = 0;
  size_t np = nb / BITS_PER_BYTE_T; /* in Bytes */

  if( sign ) sn = 1;

  switch( nb )
  {
    case NBR_32:
      (void)memcpy( (void *)ee, (void *)&_e_nanmax_32_[sn][0],     np );
      break;
    case NBR_64:
      (void)memcpy( (void *)ee, (void *)&_e_nanmax_64_[sn][0],     np );
      break;
    case NBR_128:
      (void)memcpy( (void *)ee, (void *)&_e_nanmax_128_[sn][0],    np );
      break;
    case NBR_256:
      (void)memcpy( (void *)ee, (void *)&_e_nanmax_256_[sn][0],    np );
      break;
    case NBR_512:
      (void)memcpy( (void *)ee, (void *)&_e_nanmax_512_[sn][0],    np );
      break;
    case NBR_1024:
      (void)memcpy( (void *)ee, (void *)&_e_nanmax_1024_[sn][0],   np );
      break;
    case NBR_2048:
      (void)memcpy( (void *)ee, (void *)&_e_nanmax_2048_[sn][0],   np );
      break;
    case NBR_4096:
      (void)memcpy( (void *)ee, (void *)&_e_nanmax_4096_[sn][0],   np );
      break;
    case NBR_8192:
      (void)memcpy( (void *)ee, (void *)&_e_nanmax_8192_[sn][0],   np );
      break;
    case NBR_16384:
      (void)memcpy( (void *)ee, (void *)&_e_nanmax_16384_[sn][0],  np );
      break;
    case NBR_32768:
      (void)memcpy( (void *)ee, (void *)&_e_nanmax_32768_[sn][0],  np );
      break;
    case NBR_65536:
      (void)memcpy( (void *)ee, (void *)&_e_nanmax_65536_[sn][0],  np );
      break;
    case NBR_131072:
      (void)memcpy( (void *)ee, (void *)&_e_nanmax_131072_[sn][0], np );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

} /* End of e_nanmax() */


static int e_isnanmax_32( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isnanmax_32() Работает с
                                      external e-type data
                                      struct.

 Concepts           : проверка на максимальное `не число'
                      (+/- 1.NAN)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 11.......11,

                      которое не равно nan_min и ind.

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( max `не число' ) [rc = 1];
                      else                 [rc = 0];

 ***************************************************************/
{
  __mpu_uint32_t *e;
  int             rc = 0;   /* Return Code */

  e = (__mpu_uint32_t *)ee;

  if( nb != NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return( rc );
  }

  /* skip Sign */
  if( (*e & 0x7fffffff) == 0x7fffffff )
    rc = 1;

  return( rc );

} /* End of e_isnanmax_32() */

static int e_isnanmax_64( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isnanmax_64() Работает с
                                      external e-type data
                                      struct.

 Concepts           : проверка на максимальное `не число'
                      (+/- 1.NAN)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 11.......11,

                      которое не равно nan_min и ind.

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( max `не число' ) [rc = 1];
                      else                 [rc = 0];

 ***************************************************************/
{
  __mpu_uint32_t *e;
  int             rc = 1;   /* Return Code */

  e = (__mpu_uint32_t *)ee;

  if( nb != NBR_64 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return( 0 );
  }

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  e++; /* high part of real32 data struct     */
#endif

  /* skip Sign */
  if( (*e & 0x7fffffff) == 0x7fffffff ) rc &= 1;
  else                                  rc &= 0;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  e++; /* low part of real32 data struct      */
#else
  e--;
#endif

  if( *e == 0xffffffff ) rc &= 1;
  else                   rc &= 0;

  return( rc );

} /* End of e_isnanmax_64() */

static int e_isnanmax_np( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isnanmax_np() Работает с
                                      external e-type data
                                      struct.

 Concepts           : проверка на максимальное `не число'
                      (+/- 1.NAN)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 11.......11,

                      которое не равно nan_min и ind.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( max `не число' ) [rc = 1];
                      else                 [rc = 0];

 ***************************************************************/
{
  int ie, is, np;
  int rc = 1; /* Return Code */

  np = internal_np( nb ) - 3; /* Sign, hgw, lgw */

  /*************************************************************
    NOTE:
    ====
      Compare 'Exp' and 'Significand'; skip Sign.
   */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ie = 1; is = 0;
#else
  ie = 0; is = np - 1;
#endif

  --np;

  /* skip Sign */
  if( (ee[is] & HIGHT_EXP) == HIGHT_EXP ) rc &= 1;
  else                                    rc &= 0;

  np *= SIZE_OF_EMUSHORT;

  switch( nb )
  {
    case NBR_128:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmax_128_[0][ie],    (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_256:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmax_256_[0][ie],    (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_512:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmax_512_[0][ie],    (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_1024:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmax_1024_[0][ie],   (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_2048:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmax_2048_[0][ie],   (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_4096:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmax_4096_[0][ie],   (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_8192:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmax_8192_[0][ie],   (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_16384:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmax_16384_[0][ie],  (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_32768:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmax_32768_[0][ie],  (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_65536:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmax_65536_[0][ie],  (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_131072:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmax_131072_[0][ie], (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      return( 0 );
      break;
    }
  } /* End of switch( nb ) */

  return rc;

} /* End of e_isnanmax_np() */

int e_isnanmax( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isnanmax() Работает с
                                   external e-type data struct.

 Concepts           : проверка на максимальное `не число'
                      (+/- 1.NAN)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 11.......11,

                      которое не равно nan_min и ind.

 Use Global Variable:

 Use Functions      :
                      e_isnanmax_32();            | this file
                      e_isnanmax_64();            | this file
                      e_isnanmax_np();            | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( max `не число' ) [rc = 1];
                      else                 [rc = 0];

 ***************************************************************/
{
  int rc = 0; /* Return Code */

  switch( nb )
  {
    case NBR_32    :
      rc = e_isnanmax_32( ee, nb );
      break;
    case NBR_64    :
      rc = e_isnanmax_64( ee, nb );
      break;
    case NBR_128   :
    case NBR_256   :
    case NBR_512   :
    case NBR_1024  :
    case NBR_2048  :
    case NBR_4096  :
    case NBR_8192  :
    case NBR_16384 :
    case NBR_32768 :
    case NBR_65536 :
    case NBR_131072:
      rc = e_isnanmax_np( ee, nb );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      return( rc );
      break;
    }
  } /* End of switch( nb ) */

  return( rc );

} /* End of e_isnanmax() */


#if MPU_WORD_ORDER_BIG_ENDIAN == 0
#include <r_const/ei_nanmin_emu32lsb.dfn>
#else
#include <r_const/ei_nanmin_emu32msb.dfn>
#endif

void ei_nanmin( EMUSHORT *ei, unsigned sign, int nb )
/***************************************************************

 Description        : ei_nanmin() Работает с
                                  internal e-type data struct.

 Concepts           : формирует минимальное `не число'
                      (+/- 1.NAN)

                      Sign  Exp  1. Significand
                      ==== ===== == ===========
                         S 1...1 1  00.......01,

                      которое не равно nan_max и ind.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ei;      - указатель на
                                           internal e-type
                                           data struct;
                      unsigned int sign; - знак формируемого
                                           числа;
                      int nb;            - количество бит в
                                           external e-type
                                           data struct.

 Return             : [void]

 ***************************************************************/
{
  int    sn = 0;
  size_t np = internal_np( nb ) * SIZE_OF_EMUSHORT;

  if( sign ) sn = 1;

  switch( nb )
  {
    case NBR_32:
    case NBR_64:
    case NBR_128:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmin_128_[sn][0],    np );
      break;
    case NBR_256:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmin_256_[sn][0],    np );
      break;
    case NBR_512:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmin_512_[sn][0],    np );
      break;
    case NBR_1024:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmin_1024_[sn][0],   np );
      break;
    case NBR_2048:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmin_2048_[sn][0],   np );
      break;
    case NBR_4096:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmin_4096_[sn][0],   np );
      break;
    case NBR_8192:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmin_8192_[sn][0],   np );
      break;
    case NBR_16384:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmin_16384_[sn][0],  np );
      break;
    case NBR_32768:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmin_32768_[sn][0],  np );
      break;
    case NBR_65536:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmin_65536_[sn][0],  np );
      break;
    case NBR_131072:
      (void)memcpy( (void *)ei, (void *)&_ei_nanmin_131072_[sn][0], np );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

} /* End of ei_nanmin() */

int ei_isnanmin( EMUSHORT *ei, int nb )
/***************************************************************

 Description        : ei_isnanmin() Работает с
                                    internal e-type data
                                    struct.

 Concepts           : проверка на минимальное `не число'
                      (+/- 1.NAN)

                      Sign  Exp  1. Significand
                      ==== ===== == ===========
                         S 1...1 1  00.......01,

                      которое не равно nan_max, и ind.

 Use Global Variable:

 Use Functions      :
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( min `не число' ) [rc = 1];
                      else                 [rc = 0];

 ***************************************************************/
{
  int ie, ne, is, ns;
  int rc = 0; /* Return Code */

  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*************************************************************
    NOTE:
    ====
      Compare 'Exp' and 'Significand'; skip Sign, lgw and hgw.
   */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ie = 1; is = ne + 2;
#else
  ie = ns + 2; is = 1;
#endif

  ne *= SIZE_OF_EMUSHORT;
  ns *= SIZE_OF_EMUSHORT;

  switch( nb )
  {
    case NBR_32:
    case NBR_64:
    case NBR_128:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmin_128_[0][ie],    (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmin_128_[0][is],    (size_t)ns )
        ) rc = 1;
      break;
    case NBR_256:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmin_256_[0][ie],    (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmin_256_[0][is],    (size_t)ns )
        ) rc = 1;
      break;
    case NBR_512:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmin_512_[0][ie],    (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmin_512_[0][is],    (size_t)ns )
        ) rc = 1;
      break;
    case NBR_1024:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmin_1024_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmin_1024_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_2048:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmin_2048_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmin_2048_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_4096:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmin_4096_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmin_4096_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_8192:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmin_8192_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmin_8192_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_16384:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmin_16384_[0][ie],  (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmin_16384_[0][is],  (size_t)ns )
        ) rc = 1;
      break;
    case NBR_32768:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmin_32768_[0][ie],  (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmin_32768_[0][is],  (size_t)ns )
        ) rc = 1;
      break;
    case NBR_65536:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmin_65536_[0][ie],  (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmin_65536_[0][is],  (size_t)ns )
        ) rc = 1;
      break;
    case NBR_131072:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_nanmin_131072_[0][ie], (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_nanmin_131072_[0][is], (size_t)ns )
        ) rc = 1;
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

  return rc;

} /* End of ei_isnanmin() */


#if MPU_WORD_ORDER_BIG_ENDIAN == 0
#include <r_const/e_nanmin_emu32lsb.dfn>
#else
#include <r_const/e_nanmin_emu32msb.dfn>
#endif

void e_nanmin( EMUSHORT *ee, unsigned sign, int nb )
/***************************************************************

 Description        : e_nanmin() Работает с
                                 external e-type data struct.

 Concepts           : формирует минимальное `не число'
                      (+/- 1.NAN)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 00.......01,

                      которое не равно nan_max и ind.

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee;      - указатель на
                                           external e-type
                                           data struct;
                      unsigned int sign; - знак формируемого
                                           числа;
                      int nb;            - количество бит в
                                           external e-type
                                           data struct.

 Return             : [void];

 ***************************************************************/
{
  int    sn = 0;
  size_t np = nb / BITS_PER_BYTE_T; /* in Bytes */

  if( sign ) sn = 1;

  switch( nb )
  {
    case NBR_32:
      (void)memcpy( (void *)ee, (void *)&_e_nanmin_32_[sn][0],     np );
      break;
    case NBR_64:
      (void)memcpy( (void *)ee, (void *)&_e_nanmin_64_[sn][0],     np );
      break;
    case NBR_128:
      (void)memcpy( (void *)ee, (void *)&_e_nanmin_128_[sn][0],    np );
      break;
    case NBR_256:
      (void)memcpy( (void *)ee, (void *)&_e_nanmin_256_[sn][0],    np );
      break;
    case NBR_512:
      (void)memcpy( (void *)ee, (void *)&_e_nanmin_512_[sn][0],    np );
      break;
    case NBR_1024:
      (void)memcpy( (void *)ee, (void *)&_e_nanmin_1024_[sn][0],   np );
      break;
    case NBR_2048:
      (void)memcpy( (void *)ee, (void *)&_e_nanmin_2048_[sn][0],   np );
      break;
    case NBR_4096:
      (void)memcpy( (void *)ee, (void *)&_e_nanmin_4096_[sn][0],   np );
      break;
    case NBR_8192:
      (void)memcpy( (void *)ee, (void *)&_e_nanmin_8192_[sn][0],   np );
      break;
    case NBR_16384:
      (void)memcpy( (void *)ee, (void *)&_e_nanmin_16384_[sn][0],  np );
      break;
    case NBR_32768:
      (void)memcpy( (void *)ee, (void *)&_e_nanmin_32768_[sn][0],  np );
      break;
    case NBR_65536:
      (void)memcpy( (void *)ee, (void *)&_e_nanmin_65536_[sn][0],  np );
      break;
    case NBR_131072:
      (void)memcpy( (void *)ee, (void *)&_e_nanmin_131072_[sn][0], np );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

} /* End of e_nanmin() */

static int e_isnanmin_32( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isnanmin_32() Работает с
                                      external e-type data
                                      struct.

 Concepts           : проверка на минимальное `не число'
                      (+/- 1.NAN)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 00.......01,

                      которое не равно nan_max и ind.

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( min `не число') [rc = 1];
                      else                [rc = 0];

 ***************************************************************/
{
  __mpu_uint32_t *e;
  int             rc = 0;   /* Return Code */

  e = (__mpu_uint32_t *)ee;

  if( nb != NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return( rc );
  }

  /* skip Sign */
  if( (*e & 0x7fffffff) == 0x7f800001 )
    rc = 1;

  return( rc );

} /* End of e_isnanmin_32() */

static int e_isnanmin_64( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isnanmin_64() Работает с
                                      external e-type data
                                      struct.

 Concepts           : проверка на минимальное `не число'
                      (+/- 1.NAN)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 00.......01,

                      которое не равно nan_max и ind.

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( min `не число' ) [rc = 1];
                      else                 [rc = 0];

 ***************************************************************/
{
  __mpu_uint32_t *e;
  int             rc = 1;   /* Return Code */

  e = (__mpu_uint32_t *)ee;

  if( nb != NBR_64 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return( 0 );
  }

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  e++; /* high part of real32 data struct     */
#endif

  /* skip Sign */
  if( (*e & 0x7fffffff) == 0x7ff00000 ) rc &= 1;
  else                                  rc &= 0;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  e++; /* low part of real32 data struct      */
#else
  e--;
#endif

  if( *e == 0x00000001 ) rc &= 1;
  else                   rc &= 0;

  return( rc );

} /* End of e_isnanmin_64() */

static int e_isnanmin_np( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isnanmin_np() Работает с
                                      external e-type data
                                      struct.

 Concepts           : проверка на минимальное `не число'
                      (+/- 1.NAN)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 00.......01,

                      которое не равно nan_max и ind.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( min `не число' ) [rc = 1];
                      else                 [rc = 0];

 ***************************************************************/
{
  int ie, is, np;
  int rc = 1; /* Return Code */

  np = internal_np( nb ) - 3; /* Sign, hgw, lgw */

  /*************************************************************
    NOTE:
    ====
      Compare 'Exp' and 'Significand'; skip Sign.
   */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ie = 1; is = 0;
#else
  ie = 0; is = np - 1;
#endif

  --np;

  /* skip Sign */
  if( (ee[is] & HIGHT_EXP) == HIGHT_EXP ) rc &= 1;
  else                                    rc &= 0;

  np *= SIZE_OF_EMUSHORT;

  switch( nb )
  {
    case NBR_128:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmin_128_[0][ie],    (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_256:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmin_256_[0][ie],    (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_512:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmin_512_[0][ie],    (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_1024:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmin_1024_[0][ie],   (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_2048:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmin_2048_[0][ie],   (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_4096:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmin_4096_[0][ie],   (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_8192:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmin_8192_[0][ie],   (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_16384:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmin_16384_[0][ie],  (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_32768:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmin_32768_[0][ie],  (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_65536:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmin_65536_[0][ie],  (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;
    case NBR_131072:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_nanmin_131072_[0][ie], (size_t)np ) ) rc &= 1;
      else                                                                            rc &= 0;
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      return( 0 );
      break;
    }
  } /* End of switch( nb ) */

  return rc;

} /* End of e_isnanmin_np() */

int e_isnanmin( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isnanmin() Работает с
                                   external e-type data struct.

 Concepts           : проверка на минимальное `не число'
                      (+/- 1.NAN)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 00.......01,

                      которое не равно nan_max и ind.

 Use Global Variable:

 Use Functions      :
                      e_isnanmin_32();            | this file
                      e_isnanmin_64();            | this file
                      e_isnanmin_np();            | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( min `не число' ) [rc = 1];
                      else                 [rc = 0];

 ***************************************************************/
{
  int rc = 0; /* Return Code */

  switch( nb )
  {
    case NBR_32    :
      rc = e_isnanmin_32( ee, nb );
      break;
    case NBR_64    :
      rc = e_isnanmin_64( ee, nb );
      break;
    case NBR_128   :
    case NBR_256   :
    case NBR_512   :
    case NBR_1024  :
    case NBR_2048  :
    case NBR_4096  :
    case NBR_8192  :
    case NBR_16384 :
    case NBR_32768 :
    case NBR_65536 :
    case NBR_131072:
      rc = e_isnanmin_np( ee, nb );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      return( rc );
      break;
    }
  } /* End of switch( nb ) */

  return( rc );

} /* End of e_isnanmin() */


#if MPU_WORD_ORDER_BIG_ENDIAN == 0
#include <r_const/ei_inf_emu32lsb.dfn>
#else
#include <r_const/ei_inf_emu32msb.dfn>
#endif

void ei_infin( EMUSHORT *ei, unsigned sign, int nb )
/***************************************************************

 Description        : ei_infin() Работает с
                                 internal e-type data struct.

 Concepts           : формирует `бесконечность' (+/- 1.INF)

                      Sign  Exp  1. Significand
                      ==== ===== == ===========
                         S 1...1 1  00.......00,

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ei;      - указатель на
                                           internal e-type
                                           data struct;
                      unsigned int sign; - знак формируемого
                                           числа;
                      int nb;            - количество бит в
                                           external e-type
                                           data struct.

 Return             : [void]

 ***************************************************************/
{
  int    sn = 0;
  size_t np = internal_np( nb ) * SIZE_OF_EMUSHORT;

  if( sign ) sn = 1;

  switch( nb )
  {
    case NBR_32:
    case NBR_64:
    case NBR_128:
      (void)memcpy( (void *)ei, (void *)&_ei_inf_128_[sn][0],    np );
      break;
    case NBR_256:
      (void)memcpy( (void *)ei, (void *)&_ei_inf_256_[sn][0],    np );
      break;
    case NBR_512:
      (void)memcpy( (void *)ei, (void *)&_ei_inf_512_[sn][0],    np );
      break;
    case NBR_1024:
      (void)memcpy( (void *)ei, (void *)&_ei_inf_1024_[sn][0],   np );
      break;
    case NBR_2048:
      (void)memcpy( (void *)ei, (void *)&_ei_inf_2048_[sn][0],   np );
      break;
    case NBR_4096:
      (void)memcpy( (void *)ei, (void *)&_ei_inf_4096_[sn][0],   np );
      break;
    case NBR_8192:
      (void)memcpy( (void *)ei, (void *)&_ei_inf_8192_[sn][0],   np );
      break;
    case NBR_16384:
      (void)memcpy( (void *)ei, (void *)&_ei_inf_16384_[sn][0],  np );
      break;
    case NBR_32768:
      (void)memcpy( (void *)ei, (void *)&_ei_inf_32768_[sn][0],  np );
      break;
    case NBR_65536:
      (void)memcpy( (void *)ei, (void *)&_ei_inf_65536_[sn][0],  np );
      break;
    case NBR_131072:
      (void)memcpy( (void *)ei, (void *)&_ei_inf_131072_[sn][0], np );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

} /* End of ei_infin() */

int ei_isinfin( EMUSHORT *ei, int nb )
/***************************************************************

 Description        : ei_ininfin() Работает с
                                   internal e-type data struct.

 Concepts           : проверка на `бесконечность' (+/- 1.INF)

                      Sign  Exp  1. Significand
                      ==== ===== == ===========
                         S 1...1 1  00.......00,

 Use Global Variable:

 Use Functions      :
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( `бесконечность' ) [rc = 1];
                      else                  [rc = 0];

 ***************************************************************/
{
  int ie, ne, is, ns;
  int rc = 0; /* Return Code */

  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*************************************************************
    NOTE:
    ====
      Compare 'Exp' and 'Significand'; skip Sign, lgw and hgw.
   */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ie = 1; is = ne + 2;
#else
  ie = ns + 2; is = 1;
#endif

  ne *= SIZE_OF_EMUSHORT;
  ns *= SIZE_OF_EMUSHORT;

  switch( nb )
  {
    case NBR_32:
    case NBR_64:
    case NBR_128:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_inf_128_[0][ie],    (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_inf_128_[0][is],    (size_t)ns )
        ) rc = 1;
      break;
    case NBR_256:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_inf_256_[0][ie],    (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_inf_256_[0][is],    (size_t)ns )
        ) rc = 1;
      break;
    case NBR_512:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_inf_512_[0][ie],    (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_inf_512_[0][is],    (size_t)ns )
        ) rc = 1;
      break;
    case NBR_1024:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_inf_1024_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_inf_1024_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_2048:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_inf_2048_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_inf_2048_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_4096:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_inf_4096_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_inf_4096_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_8192:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_inf_8192_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_inf_8192_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_16384:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_inf_16384_[0][ie],  (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_inf_16384_[0][is],  (size_t)ns )
        ) rc = 1;
      break;
    case NBR_32768:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_inf_32768_[0][ie],  (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_inf_32768_[0][is],  (size_t)ns )
        ) rc = 1;
      break;
    case NBR_65536:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_inf_65536_[0][ie],  (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_inf_65536_[0][is],  (size_t)ns )
        ) rc = 1;
      break;
    case NBR_131072:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_inf_131072_[0][ie], (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_inf_131072_[0][is], (size_t)ns )
        ) rc = 1;
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

  return rc;

} /* End of ei_isinfin() */


#if MPU_WORD_ORDER_BIG_ENDIAN == 0
#include <r_const/e_inf_emu32lsb.dfn>
#else
#include <r_const/e_inf_emu32msb.dfn>
#endif

void e_infin( EMUSHORT *ee, unsigned sign, int nb )
/***************************************************************

 Description        : e_infin() Работает с
                                external e-type data struct.

 Concepts           : формирует `бесконечность' (+/- 1.INF)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 00.......00,

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee;      - указатель на
                                           external e-type
                                           data struct;
                      unsigned int sign; - знак формируемого
                                           числа;
                      int nb;            - количество бит в
                                           external e-type
                                           data struct.

 Return             : [void];

 ***************************************************************/
{
  int    sn = 0;
  size_t np = nb / BITS_PER_BYTE_T; /* in Bytes */

  if( sign ) sn = 1;

  switch( nb )
  {
    case NBR_32:
      (void)memcpy( (void *)ee, (void *)&_e_inf_32_[sn][0],     np );
      break;
    case NBR_64:
      (void)memcpy( (void *)ee, (void *)&_e_inf_64_[sn][0],     np );
      break;
    case NBR_128:
      (void)memcpy( (void *)ee, (void *)&_e_inf_128_[sn][0],    np );
      break;
    case NBR_256:
      (void)memcpy( (void *)ee, (void *)&_e_inf_256_[sn][0],    np );
      break;
    case NBR_512:
      (void)memcpy( (void *)ee, (void *)&_e_inf_512_[sn][0],    np );
      break;
    case NBR_1024:
      (void)memcpy( (void *)ee, (void *)&_e_inf_1024_[sn][0],   np );
      break;
    case NBR_2048:
      (void)memcpy( (void *)ee, (void *)&_e_inf_2048_[sn][0],   np );
      break;
    case NBR_4096:
      (void)memcpy( (void *)ee, (void *)&_e_inf_4096_[sn][0],   np );
      break;
    case NBR_8192:
      (void)memcpy( (void *)ee, (void *)&_e_inf_8192_[sn][0],   np );
      break;
    case NBR_16384:
      (void)memcpy( (void *)ee, (void *)&_e_inf_16384_[sn][0],  np );
      break;
    case NBR_32768:
      (void)memcpy( (void *)ee, (void *)&_e_inf_32768_[sn][0],  np );
      break;
    case NBR_65536:
      (void)memcpy( (void *)ee, (void *)&_e_inf_65536_[sn][0],  np );
      break;
    case NBR_131072:
      (void)memcpy( (void *)ee, (void *)&_e_inf_131072_[sn][0], np );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

} /* End of e_infin() */

static int e_isinfin_32( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isinfin_32() Работает с
                                     external e-type data
                                     struct.

 Concepts           : проверка на `бесконечность' (+/- 1.INF)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 00.......00,

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( `бесконечность' ) [rc = 1];
                      else                  [rc = 0];

 ***************************************************************/
{
  __mpu_uint32_t *e;
  int             rc = 0;   /* Return Code */

  e = (__mpu_uint32_t *)ee;

  if( nb != NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return( rc );
  }

  /* skip Sign */
  if( (*e & 0x7fffffff) == 0x7f800000 )
    rc = 1;

  return( rc );

} /* End of e_isinfin_32() */

static int e_isinfin_64( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isinfin_64() Работает с
                                     external e-type data
                                     struct.

 Concepts           : проверка на `бесконечность' (+/- 1.INF)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 00.......0,

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( `бесконечность' ) [rc = 1];
                      else                  [rc = 0];

 ***************************************************************/
{
  __mpu_uint32_t *e;
  int             rc = 1;   /* Return Code */

  e = (__mpu_uint32_t *)ee;

  if( nb != NBR_64 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return( 0 );
  }

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  e++; /* high part of real32 data struct     */
#endif

  /* skip Sign */
  if( (*e & 0x7fffffff) == 0x7ff00000 ) rc &= 1;
  else                                  rc &= 0;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  e++; /* low part of real32 data struct      */
#else
  e--;
#endif

  if( *e == 0x00000000 ) rc &= 1;
  else                   rc &= 0;

  return( rc );

} /* End of e_isinfin_64() */

static int e_isinfin_np( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_ininfin_np() Работает с
                                     external e-type data
                                     struct.

 Concepts           : проверка на `бесконечность' (+/- 1.INF)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 00.......00,

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( `бесконечность' ) [rc = 1];
                      else                  [rc = 0];

 ***************************************************************/
{
  int ie, is, np;
  int rc = 1; /* Return Code */

  np = internal_np( nb ) - 3; /* Sign, hgw, lgw */

  /*************************************************************
    NOTE:
    ====
      Compare 'Exp' and 'Significand'; skip Sign.
   */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ie = 1; is = 0;
#else
  ie = 0; is = np - 1;
#endif

  --np;

  /* skip Sign */
  if( (ee[is] & HIGHT_EXP) == HIGHT_EXP ) rc &= 1;
  else                                    rc &= 0;

  np *= SIZE_OF_EMUSHORT;

  switch( nb )
  {
    case NBR_128:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_inf_128_[0][ie],    (size_t)np ) ) rc &= 1;
      else                                                                         rc &= 0;
      break;
    case NBR_256:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_inf_256_[0][ie],    (size_t)np ) ) rc &= 1;
      else                                                                         rc &= 0;
      break;
    case NBR_512:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_inf_512_[0][ie],    (size_t)np ) ) rc &= 1;
      else                                                                         rc &= 0;
      break;
    case NBR_1024:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_inf_1024_[0][ie],   (size_t)np ) ) rc &= 1;
      else                                                                         rc &= 0;
      break;
    case NBR_2048:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_inf_2048_[0][ie],   (size_t)np ) ) rc &= 1;
      else                                                                         rc &= 0;
      break;
    case NBR_4096:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_inf_4096_[0][ie],   (size_t)np ) ) rc &= 1;
      else                                                                         rc &= 0;
      break;
    case NBR_8192:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_inf_8192_[0][ie],   (size_t)np ) ) rc &= 1;
      else                                                                         rc &= 0;
      break;
    case NBR_16384:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_inf_16384_[0][ie],  (size_t)np ) ) rc &= 1;
      else                                                                         rc &= 0;
      break;
    case NBR_32768:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_inf_32768_[0][ie],  (size_t)np ) ) rc &= 1;
      else                                                                         rc &= 0;
      break;
    case NBR_65536:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_inf_65536_[0][ie],  (size_t)np ) ) rc &= 1;
      else                                                                         rc &= 0;
      break;
    case NBR_131072:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_inf_131072_[0][ie], (size_t)np ) ) rc &= 1;
      else                                                                         rc &= 0;
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      return( 0 );
      break;
    }
  } /* End of switch( nb ) */

  return rc;

} /* End of e_isinfin_np() */

int e_isinfin( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isinfin() Работает с
                                  external e-type data struct.

 Concepts           : проверка на `бесконечность' (+/- 1.INF)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1...1 00.......00,

 Use Global Variable:

 Use Functions      :
                      e_isinfin_32();             | this file
                      e_isinfin_64();             | this file
                      e_isinfin_np();             | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( `бесконечность' ) [rc = 1];
                      else                  [rc = 0];

 ***************************************************************/
{
  int  rc = 0; /* Return Code */

  switch( nb )
  {
    case NBR_32    :
      rc = e_isinfin_32( ee, nb );
      break;
    case NBR_64    :
      rc = e_isinfin_64( ee, nb );
      break;
    case NBR_128   :
    case NBR_256   :
    case NBR_512   :
    case NBR_1024  :
    case NBR_2048  :
    case NBR_4096  :
    case NBR_8192  :
    case NBR_16384 :
    case NBR_32768 :
    case NBR_65536 :
    case NBR_131072:
      rc = e_isinfin_np( ee, nb );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      return( rc );
      break;
    }
  } /* End of switch( nb ) */

  return( rc );

} /* End of e_isinfin() */


#if MPU_WORD_ORDER_BIG_ENDIAN == 0
#include <r_const/e_realmin_emu32lsb.dfn>
#else
#include <r_const/e_realmin_emu32msb.dfn>
#endif

void e_realmin( EMUSHORT *ee, unsigned sign, int nb )
/***************************************************************

 Description        : e_realmin() Работает с
                                  external e-type data struct.

 Concepts           : формирует `минимальное число'

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 0..01 00.......00,

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee;      - указатель на
                                           external e-type
                                           data struct;
                      unsigned int sign; - знак формируемого
                                           числа;
                      int nb;            - количество бит в
                                           external e-type
                                           data struct.

 Return             : [void];

 ***************************************************************/
{
  int    sn = 0;
  size_t np = nb / BITS_PER_BYTE_T; /* in Bytes */

  if( sign ) sn = 1;

  switch( nb )
  {
    case NBR_32:
      (void)memcpy( (void *)ee, (void *)&_e_realmin_32_[sn][0],     np );
      break;
    case NBR_64:
      (void)memcpy( (void *)ee, (void *)&_e_realmin_64_[sn][0],     np );
      break;
    case NBR_128:
      (void)memcpy( (void *)ee, (void *)&_e_realmin_128_[sn][0],    np );
      break;
    case NBR_256:
      (void)memcpy( (void *)ee, (void *)&_e_realmin_256_[sn][0],    np );
      break;
    case NBR_512:
      (void)memcpy( (void *)ee, (void *)&_e_realmin_512_[sn][0],    np );
      break;
    case NBR_1024:
      (void)memcpy( (void *)ee, (void *)&_e_realmin_1024_[sn][0],   np );
      break;
    case NBR_2048:
      (void)memcpy( (void *)ee, (void *)&_e_realmin_2048_[sn][0],   np );
      break;
    case NBR_4096:
      (void)memcpy( (void *)ee, (void *)&_e_realmin_4096_[sn][0],   np );
      break;
    case NBR_8192:
      (void)memcpy( (void *)ee, (void *)&_e_realmin_8192_[sn][0],   np );
      break;
    case NBR_16384:
      (void)memcpy( (void *)ee, (void *)&_e_realmin_16384_[sn][0],  np );
      break;
    case NBR_32768:
      (void)memcpy( (void *)ee, (void *)&_e_realmin_32768_[sn][0],  np );
      break;
    case NBR_65536:
      (void)memcpy( (void *)ee, (void *)&_e_realmin_65536_[sn][0],  np );
      break;
    case NBR_131072:
      (void)memcpy( (void *)ee, (void *)&_e_realmin_131072_[sn][0], np );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

} /* End of e_realmin() */


#if MPU_WORD_ORDER_BIG_ENDIAN == 0
#include <r_const/e_realmax_emu32lsb.dfn>
#else
#include <r_const/e_realmax_emu32msb.dfn>
#endif

void e_realmax( EMUSHORT *ee, unsigned sign, int nb )
/***************************************************************

 Description        : e_realmax() Работает с
                                  external e-type data struct.

 Concepts           : формирует `максимальное число' (+/- 0.0)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 1..10 11.......11,

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee;      - указатель на
                                           external e-type
                                           data struct;
                      unsigned int sign; - знак формируемого
                                           числа;
                      int nb;            - количество бит в
                                           external e-type
                                           data struct.

 Return             : [void];

 ***************************************************************/
{
  int    sn = 0;
  size_t np = nb / BITS_PER_BYTE_T; /* in Bytes */

  if( sign ) sn = 1;

  switch( nb )
  {
    case NBR_32:
      (void)memcpy( (void *)ee, (void *)&_e_realmax_32_[sn][0],     np );
      break;
    case NBR_64:
      (void)memcpy( (void *)ee, (void *)&_e_realmax_64_[sn][0],     np );
      break;
    case NBR_128:
      (void)memcpy( (void *)ee, (void *)&_e_realmax_128_[sn][0],    np );
      break;
    case NBR_256:
      (void)memcpy( (void *)ee, (void *)&_e_realmax_256_[sn][0],    np );
      break;
    case NBR_512:
      (void)memcpy( (void *)ee, (void *)&_e_realmax_512_[sn][0],    np );
      break;
    case NBR_1024:
      (void)memcpy( (void *)ee, (void *)&_e_realmax_1024_[sn][0],   np );
      break;
    case NBR_2048:
      (void)memcpy( (void *)ee, (void *)&_e_realmax_2048_[sn][0],   np );
      break;
    case NBR_4096:
      (void)memcpy( (void *)ee, (void *)&_e_realmax_4096_[sn][0],   np );
      break;
    case NBR_8192:
      (void)memcpy( (void *)ee, (void *)&_e_realmax_8192_[sn][0],   np );
      break;
    case NBR_16384:
      (void)memcpy( (void *)ee, (void *)&_e_realmax_16384_[sn][0],  np );
      break;
    case NBR_32768:
      (void)memcpy( (void *)ee, (void *)&_e_realmax_32768_[sn][0],  np );
      break;
    case NBR_65536:
      (void)memcpy( (void *)ee, (void *)&_e_realmax_65536_[sn][0],  np );
      break;
    case NBR_131072:
      (void)memcpy( (void *)ee, (void *)&_e_realmax_131072_[sn][0], np );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

} /* End of e_realmax() */


#if MPU_WORD_ORDER_BIG_ENDIAN == 0
#include <r_const/ei_null_emu32lsb.dfn>
#else
#include <r_const/ei_null_emu32msb.dfn>
#endif

void ei_signull( EMUSHORT *ei, unsigned sign, int nb )
/***************************************************************

 Description        : ei_signull() Работает с
                                   internal e-type data struct.

 Concepts           : формирует `знаковый ноль' (+/- 0.0)

                      Sign  Exp  1. Significand
                      ==== ===== == ===========
                         S 0..00 0  00.......00,

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ei;      - указатель на
                                           internal e-type
                                           data struct;
                      unsigned int sign; - знак формируемого
                                           числа;
                      int nb;            - количество бит в
                                           external e-type
                                           data struct.

 Return             : [void]

 ***************************************************************/
{
  int  sn = 0;
  int  np = internal_np( nb );

  (void)memset( (void *)ei, 0, np * SIZE_OF_EMUSHORT );

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  sn = np - 1;
#endif

  if( sign )
    ei[sn] = MASK_ALL_BITS;

} /* End of ei_signull() */

int ei_issignull( EMUSHORT *ei, int nb )
/***************************************************************

 Description        : ei_issignull() Работает с
                                     internal e-type data struct.

 Concepts           : проверка на `знаковый ноль' (+/- 0.0)

                      Sign  Exp  1. Significand
                      ==== ===== == ===========
                         S 0..00 0  00.......00,

 Use Global Variable:

 Use Functions      :
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( `знаковый ноль' ) [rc = 1];
                      else                  [rc = 0];

 ***************************************************************/
{
  int ie, ne, is, ns;
  int rc = 0; /* Return Code */

  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*************************************************************
    NOTE:
    ====
      Compare 'Exp' and 'Significand'; skip Sign, lgw and hgw.
   */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ie = 1; is = ne + 2;
#else
  ie = ns + 2; is = 1;
#endif

  ne *= SIZE_OF_EMUSHORT;
  ns *= SIZE_OF_EMUSHORT;

  switch( nb )
  {
    case NBR_32:
    case NBR_64:
    case NBR_128:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_null_128_[0][ie],    (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_null_128_[0][is],    (size_t)ns )
        ) rc = 1;
      break;
    case NBR_256:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_null_256_[0][ie],    (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_null_256_[0][is],    (size_t)ns )
        ) rc = 1;
      break;
    case NBR_512:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_null_512_[0][ie],    (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_null_512_[0][is],    (size_t)ns )
        ) rc = 1;
      break;
    case NBR_1024:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_null_1024_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_null_1024_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_2048:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_null_2048_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_null_2048_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_4096:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_null_4096_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_null_4096_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_8192:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_null_8192_[0][ie],   (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_null_8192_[0][is],   (size_t)ns )
        ) rc = 1;
      break;
    case NBR_16384:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_null_16384_[0][ie],  (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_null_16384_[0][is],  (size_t)ns )
        ) rc = 1;
      break;
    case NBR_32768:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_null_32768_[0][ie],  (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_null_32768_[0][is],  (size_t)ns )
        ) rc = 1;
      break;
    case NBR_65536:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_null_65536_[0][ie],  (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_null_65536_[0][is],  (size_t)ns )
        ) rc = 1;
      break;
    case NBR_131072:
      if( !memcmp( (void *)&ei[ie], (void *)&_ei_null_131072_[0][ie], (size_t)ne ) &&
          !memcmp( (void *)&ei[is], (void *)&_ei_null_131072_[0][is], (size_t)ns )
        ) rc = 1;
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

  return rc;

} /* End of ei_issignull() */


#if MPU_WORD_ORDER_BIG_ENDIAN == 0
#include <r_const/e_null_emu32lsb.dfn>
#else
#include <r_const/e_null_emu32msb.dfn>
#endif

void e_signull( EMUSHORT *ee, unsigned sign, int nb )
/***************************************************************

 Description        : e_signull() Работает с
                                  external e-type data
                                  struct.

 Concepts           : формирует `знаковый ноль' (+/- 0.0)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 0..00 00.......00,

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee;      - указатель на
                                           external e-type
                                           data struct;
                      unsigned int sign; - знак формируемого
                                           числа;
                      int nb;            - количество бит в
                                           external e-type
                                           data struct.

 Return             : [void]

 ***************************************************************/
{
  int    sn = 0;
  size_t np = nb / BITS_PER_BYTE_T; /* in Bytes */

  if( sign ) sn = 1;

  switch( nb )
  {
    case NBR_32:
      (void)memcpy( (void *)ee, (void *)&_e_null_32_[sn][0],     np );
      break;
    case NBR_64:
      (void)memcpy( (void *)ee, (void *)&_e_null_64_[sn][0],     np );
      break;
    case NBR_128:
      (void)memcpy( (void *)ee, (void *)&_e_null_128_[sn][0],    np );
      break;
    case NBR_256:
      (void)memcpy( (void *)ee, (void *)&_e_null_256_[sn][0],    np );
      break;
    case NBR_512:
      (void)memcpy( (void *)ee, (void *)&_e_null_512_[sn][0],    np );
      break;
    case NBR_1024:
      (void)memcpy( (void *)ee, (void *)&_e_null_1024_[sn][0],   np );
      break;
    case NBR_2048:
      (void)memcpy( (void *)ee, (void *)&_e_null_2048_[sn][0],   np );
      break;
    case NBR_4096:
      (void)memcpy( (void *)ee, (void *)&_e_null_4096_[sn][0],   np );
      break;
    case NBR_8192:
      (void)memcpy( (void *)ee, (void *)&_e_null_8192_[sn][0],   np );
      break;
    case NBR_16384:
      (void)memcpy( (void *)ee, (void *)&_e_null_16384_[sn][0],  np );
      break;
    case NBR_32768:
      (void)memcpy( (void *)ee, (void *)&_e_null_32768_[sn][0],  np );
      break;
    case NBR_65536:
      (void)memcpy( (void *)ee, (void *)&_e_null_65536_[sn][0],  np );
      break;
    case NBR_131072:
      (void)memcpy( (void *)ee, (void *)&_e_null_131072_[sn][0], np );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

} /* End of e_signull() */

static int e_issignull_32( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_issignull_32() Работает с
                                      external e-type data
                                      struct.

 Concepts           : проверка на `знаковый ноль' (+/- 0.0)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 0..00 00.......00,

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( `знаковый ноль' ) [rc = 1];
                      else                  [rc = 0];

 ***************************************************************/
{
  __mpu_uint32_t *e;
  int             rc = 0;   /* Return Code */

  e = (__mpu_uint32_t *)ee;

  if( nb != NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return( rc );
  }

  /* skip Sign */
  if( (*e & 0x7fffffff) == (__mpu_uint32_t)0 )
    rc = 1;

  return( rc );

} /* End of e_issignull_32() */

static int e_issignull_64( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_issignull_64() Работает с
                                      external e-type data
                                      struct.

 Concepts           : проверка на `знаковый ноль' (+/- 0.0)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 0..00 00.......00,

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( `знаковый ноль' ) [rc = 1];
                      else                  [rc = 0];

 ***************************************************************/
{
  __mpu_uint32_t *e;
  int             rc = 1;   /* Return Code */

  e = (__mpu_uint32_t *)ee;

  if( nb != NBR_64 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return( 0 );
  }

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  e++; /* high part of real32 data struct     */
#endif

  /* skip Sign */
  if( (*e & 0x7fffffff) == (__mpu_uint32_t)0 ) rc &= 1;
  else                                         rc &= 0;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  e++; /* low part of real32 data struct      */
#else
  e--;
#endif

  if( *e == (__mpu_uint32_t)0 ) rc &= 1;
  else                          rc &= 0;

  return( rc );

} /* End of e_issignull_64() */

static int e_issignull_np( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_issignull_np() Работает с
                                      external e-type data
                                      struct.

 Concepts           : проверка на `знаковый ноль' (+/- 0.0)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 0..00 00.......00,

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( `знаковый ноль' ) [rc = 1];
                      else                  [rc = 0];

 ***************************************************************/
{
  int ie, is, np;
  int rc = 1; /* Return Code */

  np = internal_np( nb ) - 3; /* Sign, hgw, lgw */

  /*************************************************************
    NOTE:
    ====
      Compare 'Exp' and 'Significand'; skip Sign.
   */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ie = 1; is = 0;
#else
  ie = 0; is = np - 1;
#endif

  --np;

  /* skip Sign */
  if( (ee[is] & HIGHT_EXP) == (EMUSHORT)0 ) rc &= 1;
  else                                      rc &= 0;

  np *= SIZE_OF_EMUSHORT;

  switch( nb )
  {
    case NBR_128:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_null_128_[0][ie],    (size_t)np ) ) rc &= 1;
      else                                                                          rc &= 0;
      break;
    case NBR_256:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_null_256_[0][ie],    (size_t)np ) ) rc &= 1;
      else                                                                          rc &= 0;
      break;
    case NBR_512:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_null_512_[0][ie],    (size_t)np ) ) rc &= 1;
      else                                                                          rc &= 0;
      break;
    case NBR_1024:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_null_1024_[0][ie],   (size_t)np ) ) rc &= 1;
      else                                                                          rc &= 0;
      break;
    case NBR_2048:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_null_2048_[0][ie],   (size_t)np ) ) rc &= 1;
      else                                                                          rc &= 0;
      break;
    case NBR_4096:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_null_4096_[0][ie],   (size_t)np ) ) rc &= 1;
      else                                                                          rc &= 0;
      break;
    case NBR_8192:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_null_8192_[0][ie],   (size_t)np ) ) rc &= 1;
      else                                                                          rc &= 0;
      break;
    case NBR_16384:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_null_16384_[0][ie],  (size_t)np ) ) rc &= 1;
      else                                                                          rc &= 0;
      break;
    case NBR_32768:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_null_32768_[0][ie],  (size_t)np ) ) rc &= 1;
      else                                                                          rc &= 0;
      break;
    case NBR_65536:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_null_65536_[0][ie],  (size_t)np ) ) rc &= 1;
      else                                                                          rc &= 0;
      break;
    case NBR_131072:
      if( !memcmp( (void *)&ee[ie], (void *)&_e_null_131072_[0][ie], (size_t)np ) ) rc &= 1;
      else                                                                          rc &= 0;
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      return( 0 );
      break;
    }
  } /* End of switch( nb ) */

  return rc;

} /* End of e_issignull_np() */

int e_issignull( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_issignull() Работает с
                                   external e-type data struct.

 Concepts           : проверка на `знаковый ноль' (+/- 0.0)

                      Sign  Exp  Significand
                      ==== ===== ===========
                         S 0..00 00.......00,

 Use Global Variable:

 Use Functions      :
                      e_issignull_32();           | this file
                      e_issignull_64();           | this file
                      e_issignull_np();           | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( `знаковый ноль' ) [rc = 1];
                      else                  [rc = 0];

 ***************************************************************/
{
  int  rc = 0; /* Return Code */

  switch( nb )
  {
    case NBR_32    :
      rc = e_issignull_32( ee, nb );
      break;
    case NBR_64    :
      rc = e_issignull_64( ee, nb );
      break;
    case NBR_128   :
    case NBR_256   :
    case NBR_512   :
    case NBR_1024  :
    case NBR_2048  :
    case NBR_4096  :
    case NBR_8192  :
    case NBR_16384 :
    case NBR_32768 :
    case NBR_65536 :
    case NBR_131072:
      rc = e_issignull_np( ee, nb );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      return( rc );
      break;
    }
  } /* End of switch( nb ) */

  return( rc );

} /* End of e_issignull() */

void ei_neg( EMUSHORT *ei, int nb )
/***************************************************************

 Description        : ei_neg() Работает с
                               internal e-type data struct.

 Concepts           : Negate the e-type real number.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void]

 ***************************************************************/
{
  int  np;

  np = internal_np( nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  ei = ei + np - 1; /* go to Sign */
#endif

  *ei ^= MASK_ALL_BITS;

} /* End of ei_neg() */

int ei_isneg( EMUSHORT *ei, int nb )
/***************************************************************

 Description        : ei_isneg() Работает с
                                 internal e-type data struct.

 Concepts           : Return 1 if Sign e-type real number is
                      nonzero, else return zero.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;

 ***************************************************************/
{
  int  np;

  np = internal_np( nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  ei = ei + np - 1; /* go to Sign */
#endif

  if( *ei & MASK_ALL_BITS ) return( 1 );
  else                      return( 0 );

} /* End of ei_isneg() */

static void e_neg_32( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_neg_32() Работает с
                                 external e-type data struct.

 Concepts           : Negate the e-type real number.

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void]

 ***************************************************************/
{
  __mpu_uint16_t  *e;

  e = (__mpu_uint16_t *)ee;

  if( nb != NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  e++;      /* high part of real32 data struct */
#endif

  *e ^= 0x8000;

} /* End of e_neg_32() */

static void e_neg_64( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_neg_64() Работает с
                                 external e-type data struct.

 Concepts           : Negate the e-type real number.
 
 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void]

 ***************************************************************/
{
  __mpu_uint32_t  *e;

  e = (__mpu_uint32_t *)ee;

  if( nb != NBR_64 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  e++;      /* high part of real32 data struct */
#endif

  *e ^= 0x80000000;

} /* End of e_neg_64() */

static void e_neg_np( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_neg_np() Работает с
                                 external e-type data struct.

 Concepts           : Negate the e-type real number.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void]

 ***************************************************************/
{
  int  np;

  np = internal_np( nb ) - 3; /* Sign, hgw, lgw */

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  ee = ee + np - 1; /* go to Sign */
#endif

  *ee ^= MASK_SIGN;

} /* End of e_neg_np() */


void e_neg( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_neg() Работает с
                              external e-type data struct.

 Concepts           : Negate the e-type real number.
 
 Use Global Variable:

 Use Functions      :
                      e_neg_32();                 | this file
                      e_neg_64();                 | this file
                      e_neg_np();                 | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void];

 ***************************************************************/
{
  switch( nb )
  {
    case NBR_32    :
      e_neg_32( ee, nb );
      break;
    case NBR_64    :
      e_neg_64( ee, nb );
      break;
    case NBR_128   :
    case NBR_256   :
    case NBR_512   :
    case NBR_1024  :
    case NBR_2048  :
    case NBR_4096  :
    case NBR_8192  :
    case NBR_16384 :
    case NBR_32768 :
    case NBR_65536 :
    case NBR_131072:
      e_neg_np( ee, nb );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

  return;

} /* End of e_neg() */

static int e_isneg_32( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isneg_32() Работает с
                                   external e-type data struct.

 Concepts           : Return 1 if Sign e-type real number is
                      nonzero, else return zero.
 
 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( Sign == 1 ) [rc = 1];
                      else            [rc = 0];

 ***************************************************************/
{
  __mpu_uint16_t  *e;

  e = (__mpu_uint16_t *)ee;

  if( nb != NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return( 0 );
  }

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  e++; /* high part of real32 data struct  */
#endif

  if( *e & 0x8000 ) return( 1 );
  else              return( 0 );

} /* End of e_isneg_32() */


static int e_isneg_64( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isneg_64() Работает с
                                   external e-type data struct.

 Concepts           : Return 1 if Sign e-type real number is
                      nonzero, else return zero.
 
 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( Sign == 1 ) [rc = 1];
                      else            [rc = 0];

 ***************************************************************/
{
  __mpu_uint32_t  *e;

  e = (__mpu_uint32_t *)ee;

  if( nb != NBR_64 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return( 0 );
  }

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  e++; /* high part of real64 data struct */
#endif

  if( *e & 0x80000000 ) return( 1 );
  else                  return( 0 );

} /* End of e_isneg_64() */

static int e_isneg_np( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isneg_np() Работает с
                                   external e-type data struct.

 Concepts           : Return 1 if Sign e-type real number is
                      nonzero, else return zero.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;

 ***************************************************************/
{
  int  np;

  np = internal_np( nb ) - 3; /* Sign, hgw, lgw */

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  ee = ee + np - 1; /* go to Sign */
#endif

  if( *ee & MASK_SIGN ) return( 1 );
  else                  return( 0 );

} /* End of e_isneg_np() */

int e_isneg( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_isneg() Работает с
                                external e-type data struct.

 Concepts           : Return 1 if Sign e-type real number is
                      nonzero, else return zero.
 
 Use Global Variable:

 Use Functions      :
                      e_isneg_32();               | this file
                      e_isneg_64();               | this file
                      e_isneg_np();               | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;
                      if( Sign == 1 ) [rc = 1];
                      else            [rc = 0];

 ***************************************************************/
{
  int  rc = 0;   /* Return Code */

  switch( nb )
  {
    case NBR_32    :
      rc = e_isneg_32( ee, nb );
      break;
    case NBR_64    :
      rc = e_isneg_64( ee, nb );
      break;
    case NBR_128   :
    case NBR_256   :
    case NBR_512   :
    case NBR_1024  :
    case NBR_2048  :
    case NBR_4096  :
    case NBR_8192  :
    case NBR_16384 :
    case NBR_32768 :
    case NBR_65536 :
    case NBR_131072:
      rc = e_isneg_np( ee, nb );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

  return( rc );

} /* End of e_isneg() */


void ei_abs( EMUSHORT *ei, int nb )
/***************************************************************

 Description        : ei_abs() Работает с
                               internal e-type data struct.

 Concepts           : сбрасывает знак числа.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void]

 ***************************************************************/
{
  int  np;

  np = internal_np( nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  ei = ei + np - 1; /* go to Sign */
#endif

  *ei &= (EMUSHORT)0;

} /* End of ei_abs() */


static void e_abs_32( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_abs_32() Работает с
                                 external e-type data struct.

 Concepts           : сбрасывает знак числа.

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void]

 ***************************************************************/
{
  __mpu_uint16_t  *e;

  e = (__mpu_uint16_t *)ee;

  if( nb != NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  e++;      /* high part of real32 data struct */
#endif

  *e &= 0x7fff;

} /* End of e_abs_32() */

static void e_abs_64( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_abs_64() Работает с
                                 external e-type data struct.

 Concepts           : сбрасывает знак числа.
 
 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void]

 ***************************************************************/
{
  __mpu_uint32_t  *e;

  e = (__mpu_uint32_t *)ee;

  if( nb != NBR_64 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  e++;      /* high part of real64 data struct */
#endif

  *e &= 0x7fffffff;

} /* End of e_abs_64() */

static void e_abs_np( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_abs_np() Работает с
                                 external e-type data struct.

 Concepts           : сбрасывает знак числа.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void]

 ***************************************************************/
{
  int  np;

  np = internal_np( nb ) - 3; /* Sign, hgw, lgw */

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  ee = ee + np - 1; /* go to Sign */
#endif

  *ee &= HIGHT_EXP;

} /* End of e_abs_np() */

void e_abs( EMUSHORT *ee, int nb )
/***************************************************************

 Description        : e_abs() Работает с
                              external e-type data struct.

 Concepts           : сбрасывает знак числа.

 Use Global Variable:

 Use Functions      :
                      e_abs_32();                 | this file
                      e_abs_64();                 | this file
                      e_abs_np();                 | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void];

 ***************************************************************/
{
  switch( nb )
  {
    case NBR_32    :
      e_abs_32( ee, nb );
      break;
    case NBR_64    :
      e_abs_64( ee, nb );
      break;
    case NBR_128   :
    case NBR_256   :
    case NBR_512   :
    case NBR_1024  :
    case NBR_2048  :
    case NBR_4096  :
    case NBR_8192  :
    case NBR_16384 :
    case NBR_32768 :
    case NBR_65536 :
    case NBR_131072:
      e_abs_np( ee, nb );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

  return;

} /* End of e_abs() */



/***************************************************************
  Functions for LONG INTEGER NUMBERS.
        (for Exponent in Internal e-type data struct.)
 ***************************************************************/

int ei_cmpe( EMUSHORT *a, EMUSHORT *b, int np )
/******************************************
  SIGNED COMPARE TWO SIGNED INTEGER NUMBER
  if( a  > b ) return(  1);
  if( a == b ) return(  0);
  if( a  < b ) return( -1);
 ******************************************/
{
  EMUSHORT  p, q;
  int       i;

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  a += np - 1;
  b += np - 1;
#endif

  p = *a & MASK_SIGN;
  q = *b & MASK_SIGN;

  /* the signs are different */
  if( p != q )
  {
    if( p == (EMUSHORT)0 ) return(  1 );
    else                   return( -1 );
  }

  /* both are the same sign */
  for( i = 0; i < np; i++ )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    if( *a++ != *b++ )
#else
    if( *a-- != *b-- )
#endif
    {
      /* different */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      if( *(--a) > *(--b) )
#else
      if( *(++a) > *(++b) )
#endif
        return(  1 );
      else
        return( -1 );

    } /* End if( != ) */

  } /* End for( i = 0; i < np; i++ ) */

  return( 0 );

} /* End of ei_cmpe() */


int ei_cmp0e( EMUSHORT *a, int np )
/******************************************
  SIGNED COMPARE A with ZERO
  if( a  > 0 ) return(  1);
  if( a == 0 ) return(  0);
  if( a  < 0 ) return( -1);
 ******************************************/
{
  int  i;

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  a += np - 1;
#endif

  /* the sign are negative */
  if( *a & MASK_SIGN ) return( -1 );
  else
  {
    /* the sign are positive */
    for( i = 0; i < np; i++ )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      if( *a++ != (EMUSHORT)0 )
#else
      if( *a-- != (EMUSHORT)0 )
#endif
        return( 1 );

    } /* End for( i = 0; i < np; i++ ) */

  } /* End if( sign ) */

  return( 0 );

} /* End of ei_cmp0e() */


void ei_cpye_pack( EMUSHORT *a, EMUSHORT *b, int npa, int npb )
/*************************************************
  КОПИРОВАНИЕ БОЛЬШЕГО В МЕНЬШЕЕ (npa < npb)
 *************************************************/
{
  int  i;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  a += npa - 1; /* low part */
  b += npb - 1;
#endif

  for( i = 0; i < npa; i++ )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    *a-- = *b--;
#else
    *a++ = *b++;
#endif
  } /* End for( i = 0; i < npa; i++ ) */

} /* End of ei_cpye_pack() */

void ei_cpye_unpack( EMUSHORT *a, EMUSHORT *b, int npa, int npb )
/*************************************************
  КОПИРОВАНИЕ МЕНЬШЕГО В БОЛЬШЕЕ (npa >= npb)
 *************************************************/
{
  int  i;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  a += npa - 1; /* low part */
  b += npb - 1;
#endif

  for( i = 0; i < npb; i++ )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    *a-- = *b--;
#else
    *a++ = *b++;
#endif
  } /* End for( i = 0; i < npb; i++ ) */

  while( i < npa )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    *a-- = (EMUSHORT)0;
#else
    *a++ = (EMUSHORT)0;
#endif
    i++;
  }

} /* End of ei_cpye_unpack() */

void ei_cpye( EMUSHORT *a, EMUSHORT *b, int npa, int npb )
/*************************************************
  COPY UNSIGNED INTEGER NUMBER
 *************************************************/
{
  if( npa >= npb ) ei_cpye_unpack( a, b, npa, npb );
  else             ei_cpye_pack  ( a, b, npa, npb );
}


void ei_cvte_unpack( EMUSHORT *a, EMUSHORT *b, int npa, int npb )
/*************************************************
  КОНВЕРТИРОВАНИЕ МЕНЬШЕГО В БОЛЬШЕЕ (npa >= npb)
 *************************************************/
{
  EMUSHORT  save_sign = (EMUSHORT)0;
  int       i;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  a += npa - 1; /* low part */
  b += npb - 1;
#endif

  for( i = 0; i < npb; i++ )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    *a-- = *b--;
#else
    *a++ = *b++;
#endif
  } /* End for( i = 0; i < npb; i++ ) */


#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  b++;
#else
  b--;
#endif

  if( *b & MASK_SIGN ) save_sign = MASK_ALL_BITS;

  while( i < npa )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    *a-- = save_sign;
#else
    *a++ = save_sign;
#endif
    i++;
  }

} /* End of ei_cvte_unpack() */

void ei_cvte_pack( EMUSHORT *a, EMUSHORT *b, int npa, int npb )
/*************************************************
  КОНВЕРТИРОВАНИЕ БОЛЬШЕГО В МЕНЬШЕЕ (npa  < npb)
 *************************************************/
{
  EMUSHORT  save_sign = (EMUSHORT)0;
  int       i;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  if( *b             & MASK_SIGN ) save_sign = MASK_SIGN;
#else
  if( *(b + npb - 1) & MASK_SIGN ) save_sign = MASK_SIGN;
#endif


#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  a += npa - 1; /* low part */
  b += npb - 1;
#endif

  for( i = 0; i < npa; i++ )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    *a-- = *b--;
#else
    *a++ = *b++;
#endif
  } /* End for( i = 0; i < npa; i++ ) */

  if( save_sign )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    *(++a) |= save_sign;
#else
    *(--a) |= save_sign;
#endif
  }
  else
  {
    /* ПРИНУДИТЕЛЬНЫЙ POSITIVE */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    *(++a) &= HIGHT_EXP;
#else
    *(--a) &= HIGHT_EXP;
#endif
  }

} /* End of ei_cvte_pack() */

void ei_cvte( EMUSHORT *a, EMUSHORT *b, int npa, int npb )
/*************************************************
  CONVERT SIGNED INTEGER NUMBER
 *************************************************/
{
  if( npa >= npb ) ei_cvte_unpack( a, b, npa, npb );
  else             ei_cvte_pack  ( a, b, npa, npb );
}


void ei_adde( EMUSHORT *c, EMUSHORT *a, EMUSHORT *b, int np )
/******************************************
  ADD INTEGER NUMBER
 ******************************************/
{
  EMULONG   rc, carry = 0;
  EMUSHORT *z, *x, *y;
  int       i;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* point to low part */
  x = a + np - 1;
  y = b + np - 1;
  z = c + np - 1;
#else
  /* point to low part */
  x = a;
  y = b;
  z = c;
#endif

  for( i = 0; i < np; i++ )
  {
    rc = (EMULONG)(*x) + (EMULONG)(*y) + carry;

    if( rc & MASK_CARRY ) carry = 1;
    else                  carry = 0;

    *z = (EMUSHORT)rc;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    --x;
    --y;
    --z;
#else
    ++x;
    ++y;
    ++z;
#endif

  } /* End for( i = 0; i < np; i++ ) */

} /* End of ei_adde() */

void ei_ince( EMUSHORT *c, EMUSHORT *a, int np )
/******************************************
  INCrement INTEGER NUMBER
 ******************************************/
{
  EMULONG   rc, carry = 1;
  EMUSHORT *z, *x;
  int       i;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* point to low part */
  x = a + np - 1;
  z = c + np - 1;
#else
  /* point to low part */
  x = a;
  z = c;
#endif

  for( i = 0; i < np; i++ )
  {
    rc = (EMULONG)(*x) + carry;

    if( rc & MASK_CARRY ) carry = 1;
    else                  carry = 0;

    *z = (EMUSHORT)rc;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    --x;
    --z;
#else
    ++x;
    ++z;
#endif

  } /* End for( i = 0; i < np; i++ ) */

} /* End of ei_ince() */


void ei_sube( EMUSHORT *c, EMUSHORT *a, EMUSHORT *b, int np )
/******************************************
  SUB INTEGER NUMBER
 ******************************************/
{
  EMULONG   rc, carry = 0;
  EMUSHORT *z, *x, *y;
  int       i;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* point to low part */
  x = a + np - 1;
  y = b + np - 1;
  z = c + np - 1;
#else
  /* point to low part */
  x = a;
  y = b;
  z = c;
#endif

  for( i = 0; i < np; i++ )
  {
    rc = (EMULONG)(*x) - (EMULONG)(*y) - carry;

    if( rc & MASK_CARRY ) carry = 1;
    else                  carry = 0;

    *z = (EMUSHORT)rc;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    --x;
    --y;
    --z;
#else
    ++x;
    ++y;
    ++z;
#endif

  } /* End for( i = 0; i < np; i++ ) */

} /* End of ei_sube() */

void ei_dece( EMUSHORT *c, EMUSHORT *a, int np )
/******************************************
  DECrement INTEGER NUMBER
 ******************************************/
{
  EMULONG   rc, carry = 1;
  EMUSHORT *z, *x;
  int       i;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* point to low part */
  x = a + np - 1;
  z = c + np - 1;
#else
  /* point to low part */
  x = a;
  z = c;
#endif

  for( i = 0; i < np; i++ )
  {
    rc = (EMULONG)(*x) - carry;

    if( rc & MASK_CARRY ) carry = 1;
    else                  carry = 0;

    *z = (EMUSHORT)rc;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    --x;
    --z;
#else
    ++x;
    ++z;
#endif

  } /* End for( i = 0; i < np; i++ ) */

} /* End of ei_dece() */

void ei_nege( EMUSHORT *c, EMUSHORT *a, int np )
/******************************************
  NEGATE Signed INTEGER NUMBER
 ******************************************/
{
  EMULONG   rc, carry = 1;
  EMUSHORT *z, *x;
  int       i;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* point to low part */
  x = a + np - 1;
  z = c + np - 1;
#else
  /* point to low part */
  x = a;
  z = c;
#endif

  for( i = 0; i < np; i++ )
  {
    rc = (EMULONG)(~(*x)) + carry;

    if( rc & MASK_CARRY ) carry = 1;
    else                  carry = 0;

    *z = (EMUSHORT)rc;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    --x;
    --z;
#else
    ++x;
    ++z;
#endif

  } /* End for( i = 0; i < np; i++ ) */

} /* End of ei_nege() */

void ei_ande( EMUSHORT *c, EMUSHORT *a, EMUSHORT *b, int np )
/******************************************
  AND INTEGER NUMBER
 ******************************************/
{
  EMUSHORT *z, *x, *y;
  int       i;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* point to low part */
  x = a + np - 1;
  y = b + np - 1;
  z = c + np - 1;
#else
  /* point to low part */
  x = a;
  y = b;
  z = c;
#endif

  for( i = 0; i < np; i++ )
  {
    *z = (*x) & (*y);

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    --x;
    --y;
    --z;
#else
    ++x;
    ++y;
    ++z;
#endif

  } /* End for( i = 0; i < np; i++ ) */

} /* End of ei_ande() */


/***************************************************************
  СДВИГИ
 ***************************************************************/

#define N_SC_PARTS(b) ((b)>>POW2)
#define N_SC_BITS(b)  ((b)&(BITS_PER_EMUSHORT-1))

void ei_shrn( EMUSHORT *c, EMUSHORT *a, unsigned b, int np )
/******************************************
  SHIFT RIGHT
 ******************************************/
{
  EMUSHORT *x, *y, tmp;
  int       i, n_parts = 0, n_bits = 0;

  if( np == 0 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  if( b > BITS_PER_EMUSHORT*np )
  {
    for( i = 0; i < np; i++ ) c[i] = (EMUSHORT)0;
    return;
  }

  n_parts = N_SC_PARTS(b);
  n_bits  = N_SC_BITS(b);

  if( b == 0 )
  {
    for( i = 0; i < np; i++ ) c[i] = a[i];
    return;
  }

  if( n_parts == np )
  {
    for( i = 0; i < np; i++ ) c[i] = (EMUSHORT)0;
    return;
  }

  if( n_parts == 0 ) /* переписываем c <= a, т.к. n_bits уже != 0 */
  {
    x = a;
    y = c;

    i = np;
    while( i ) { *y = *x; x++; y++; i--; }
  }

  if( n_parts )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    x = a + np - 1 - n_parts;
    y = c + np - 1 - n_parts;
#else
    x = a + n_parts;
    y = c + n_parts;
#endif

    i = np - n_parts;
    while( i )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      *(y + n_parts) = *x;
#else
      *(y - n_parts) = *x;
#endif

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      x--;
      y--;
#else
      x++;
      y++;
#endif
      i--;
    }

    i = n_parts;
    while( i )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      y++;
#else
      y--;
#endif
      *y = 0;

      i--;
    }

  } /* End if( n_parts ) */

  if( n_bits )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    y = c + np - 1;
#else
    y = c;
#endif

    *y = *y >> n_bits;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    y--;
#else
    y++;
#endif

    i = np - 1;
    while( i )
    {
      tmp = *y;
      *y = *y >> n_bits;

      tmp = tmp << (BITS_PER_EMUSHORT-n_bits);

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      *(y + 1) |= tmp;
#else
      *(y - 1) |= tmp;
#endif

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      y--;
#else
      y++;
#endif
      i--;
    }

  } /* End if( n_bits ) */

} /* End of ei_shrn() */

void ei_shln( EMUSHORT *c, EMUSHORT *a, unsigned b, int np )
/******************************************
  SHIFT LEFT
 ******************************************/
{
  EMUSHORT *x, *y, tmp;
  int       i, n_parts = 0, n_bits = 0;

  if( np == 0 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  if( b > BITS_PER_EMUSHORT*np )
  {
    for( i = 0; i < np; i++ ) c[i] = (EMUSHORT)0;
    return;
  }

  n_parts = N_SC_PARTS(b);
  n_bits  = N_SC_BITS(b);

  if( b == 0 )
  {
    for( i = 0; i < np; i++ ) c[i] = a[i];
    return;
  }

  if( n_parts == np )
  {
    for( i = 0; i < np; i++ ) c[i] = (EMUSHORT)0;
    return;
  }

  if( n_parts == 0 ) /* переписываем c <= a, т.к. n_bits уже != 0 */
  {
    x = a;
    y = c;

    i = np;
    while( i ) { *y = *x; x++; y++; i--; }
  }

  if( n_parts )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    x = a + n_parts;
    y = c + n_parts;
#else
    x = a + np - 1 - n_parts;
    y = c + np - 1 - n_parts;
#endif

    i = np - n_parts;
    while( i )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      *(y - n_parts) = *x;
#else
      *(y + n_parts) = *x;
#endif

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      x++;
      y++;
#else
      x--;
      y--;
#endif
      i--;
    }

    i = n_parts;
    while( i )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      y--;
#else
      y++;
#endif
      *y = 0;

      i--;
    }

  } /* End if( n_parts ) */

  if( n_bits )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    y = c;
#else
    y = c + np - 1;
#endif

    *y = *y << n_bits;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    y++;
#else
    y--;
#endif

    i = np - 1;
    while( i )
    {
      tmp = *y;
      *y = *y << n_bits;

      tmp = tmp >> (BITS_PER_EMUSHORT-n_bits);

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      *(y - 1) |= tmp;
#else
      *(y + 1) |= tmp;
#endif

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      y++;
#else
      y--;
#endif
      i--;
    }

  } /* End if( n_bits ) */

} /* End of ei_shln() */

/***************************************************************
  End of Functions for LONG INTEGER NUMBERS.
 ***************************************************************/



void ei_shdown( EMUSHORT *ei, unsigned sc, int nb )
/***************************************************************

 Description        : ei_shdown() Работает с
                                  internal e-type data struct.

 Concepts           : shift right Significand of exploded
                      internal e-type data struct.
                      Guard words are included in the shift.

 Use Global Variable:

 Use Functions      :
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int sc;       - количество
                                      сдвигаемых бит.
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void]

 ***************************************************************/
{
  int  ns;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  int  ne;

  ne = internal_ne( nb );

  ei = ei + ne + 1; /* point to hgw */
#endif /* else         point to lgw */

  ns = internal_ns( nb );

  ei_shrn( ei, ei, sc, ns + 2 );

} /* End of ei_shdown() */


void ei_shup( EMUSHORT *ei, unsigned sc, int nb )
/***************************************************************

 Description        : ei_shup() Работает с
                                internal e-type data struct.

 Concepts           : shift left Significand of exploded
                      internal e-type data struct.
                      Guard words are included in the shift.

 Use Global Variable:

 Use Functions      :
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int sc;       - количество
                                      сдвигаемых бит.
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void]

 ***************************************************************/
{
  int  ns;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  int  ne;

  ne = internal_ne( nb );

  ei = ei + ne + 1; /* point to hgw */
#endif /* else         point to lgw */

  ns = internal_ns( nb );

  ei_shln( ei, ei, sc, ns + 2 );

} /* End of ei_shup() */


int ei_shift( EMUSHORT *ei, int sc, int nb )
/***************************************************************

 Description        : ei_shift() Работает с
                                 internal e-type data struct.

 Concepts           : shift the Significand of exploded
                      internal e-type data struct.
                      Guard words are included in the shift.

 Use Global Variable:

 Use Functions      :
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file
                      ei_shup( *ei, sc, nb );     | this file
                      ei_shdown( *ei, sc, nb );   | this file

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int sc;       - количество
                                      сдвигаемых бит
                                      (positive = up).
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int lost;
                      if( sc < 0 &&
                          `выдвинут хотябы один единичный бит' )
                         [lost = 1];
                      else   [lost = 0];

 ***************************************************************/
{
  EMUSHORT  lost = (EMUSHORT)0;
  EMUSHORT *p;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  int       ne;
#endif
  int       ns;

  if( sc == 0 ) return( (int)lost );

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ne = internal_ne( nb );

  p = ei + ne + 1; /* point to hgw */
#else
  p = ei;          /* point to lgw */
#endif

  ns = internal_ns( nb );

  if( sc < 0 )
  {
    int i, k, ks;

    sc = -sc;
    /********************************************
      remember lost bits
     ********************************************/
    k = EMUSHORTSIZE(sc) - 1;
    for( i = 0; i < k; i++ )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      lost |= p[ns + 1 - i];
#else
      lost |= p[i];
#endif
    }
    ks = sc - k*BITS_PER_EMUSHORT;
    for( i = 0; i < ks; i++ )
    {
      lost |= ORDER_BIT( p, i + k*BITS_PER_EMUSHORT, ns+2 );
    }
    /******* end of remember lost bits **********/

    ei_shdown( ei, (unsigned)sc, nb );

  }
  else
  {
    ei_shup( ei, (unsigned)sc, nb );
  }

  if( lost ) lost = (EMUSHORT)1;

  return( (int)lost );

} /* End of ei_shift() */



/***************************************************************
  NOTE:
     Количество бит мантиссы вещественного числа во внутреннем
     формате не должно превышать  максимального положительного
     signed EMUSHORT, которому соответствует тип __mpu_int32_t.
 ***************************************************************/

/* количество бит в Significand in Internal e-type data struct */
#define EINSBITS(nb) ((__mpu_int32_t)(internal_ns(nb)*BITS_PER_EMUSHORT))

__mpu_int32_t ei_normalize( EMUSHORT *ei, int nb )
/***************************************************************

 Description        : ei_normalize() Работает с
                                     internal e-type data
                                     struct.

 Concepts           : left-justify the Significand of exploded
                      internal e-type data struct.
                      Guard words are included in the shift.

 Use Global Variable:

 Use Functions      : 
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file
                      ei_shup( *ei, sc, nb );     | this file
                      ei_shdown( *ei, sc, nb );   | this file

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : __mpu_int32_t  sc; - shift counter.

                      if( sc < 0 )         =>  был сдвиг вверх;
                      else if( sc == 0 )   =>  сдвигов не было;
                           else            =>  был сдвиг вниз;

 ***************************************************************/
{
  __mpu_int32_t  sc = 0; /* Ret. Code (shift counter) */
  EMUSHORT      *p;
  int            ns;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  int            ne;

  ne = internal_ne( nb );

  p = ei + ne + 1; /* point to hgw */
#endif

  ns = internal_ns( nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  p = ei + ns + 1; /* point to hgw */
#endif

  if( *p == 0 ) /* normalize up (left) */
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    p++;
#else
    p--;
#endif

    if( *p & MASK_SIGN )
      return( sc ); /* already normalized (sc = 0) */

    /*******************************************
      Left-justify the Significand.
     *******************************************/
    while( *p == (EMUSHORT)0 )
    {
      ei_shup( ei, (unsigned)BITS_PER_EMUSHORT, nb );
      sc += BITS_PER_EMUSHORT;

      if( sc > EINSBITS(nb) )
      {
        /*
          With guard word, there are
          EINSBITS(nb)+BITS_PER_EMUSHORT
          bits available.
          Return true if all are zero
          (SIGNED NULL or ei_cleazs(), for example).
         */
        return( sc );
      }
    }
    /* see if high byte is zero */
    while( (*p & HIGHT_BYTE) == (EMUSHORT)0 )
    {
      ei_shup( ei, (unsigned)8, nb );
      sc += 8;
    }
    /* now shift 1 bit at a time */
    while( (*p & MASK_SIGN) == (EMUSHORT)0 )
    {
      ei_shup( ei, (unsigned)1, nb );
      sc += 1;

      if( sc > EINSBITS(nb) )
      {
        /* ONLY: выставить ошибку и вернуть SC */
        /***************************************************
          NOTE:
             Функция _mtherr() является переходником между
             внутренним форматом и внешней,
             переопределяемой пользователем, функцией
             __mpu_math_error(). Кроме основных действий
             она выставляет системную переменную errno
             следующим образом.

               errno = __mpu_math_errnotab[type];
         ***************************************************/
        _mtherr( (EMUSHORT *)0, /* Not change */
                 (__mpu_char8_t *)"ei_normalize", __UNDERFLOW__,
                 (EMUSHORT *)0,
                 (EMUSHORT *)0, (EMUSHORT *)0, nb );
        __STUDF; /* Set REAL Underflow Flag */
        return( sc );
      }
    }
  }      /* End of normalize up (left) */
  else   /* normalize down (right) */
  {
    /*******************************************
      Normalize by shifting down (right) out of
      the high guard word  of the  Significand.
     *******************************************/
    while( *p != (EMUSHORT)0 )
    {
      ei_shdown( ei, (unsigned)1, nb );
      sc -= 1;

      if( sc < - EINSBITS(nb) )
      {
        /* ONLY: выставить ошибку и вернуть SC */
        /***************************************************
          NOTE:
             Функция _mtherr() является переходником между
             внутренним форматом и внешней,
             переопределяемой пользователем, функцией
             __mpu_math_error(). Кроме основных действий
             она выставляет системную переменную errno
             следующим образом.

               errno = __mpu_math_errnotab[type];
         ***************************************************/
        _mtherr( (EMUSHORT *)0, /* Not change */
                 (__mpu_char8_t *)"ei_normalize", __OVERFLOW__,
                 (EMUSHORT *)0,
                 (EMUSHORT *)0, (EMUSHORT *)0, nb );
        __STOVF; /* Set REAL Overflow Flag */
        return( sc );
      }
    }

  } /* End of normalize down (right) */

  __CLOVF; /* Clear REAL Overflow Flag */
  __CLUDF; /* Clear REAL Underflow Flag */

  return( sc );

} /* End of ei_normalize() */


static void unpack_32( EMUSHORT *ei, EMUSHORT *ee, int nb )
/***************************************************************

 Description        : unpack_32() Распаковывает real32 data
                                  struct в internal e-type data
                                  struct.

 Concepts           :

 NOTE               : Функция работает правильно только для
                      размеров EMUSHORT кратных 16 бит
                      (16,32,48,64,80,96,...).
                      SEE operator:

                        pe += (BITS_PER_EMUSHORT - 16) / 16

                      in LITTLE_ENDIAN case.

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                                      память под нее
                                      выделяется до
                                      применения
                                      unpack_32() и
                                      ее размер на
                                      совести
                                      программиста;
                      EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void];

 ***************************************************************/
{
  EMUSHORT    *exone = NULL,
                *inc = NULL,
                  *r = NULL;
  EMUSHORT        *p;
  __mpu_uint16_t  *he, *pe;
  int              denorm = 0;
  __mpu_int32_t    k;
  int              np, ne, ns, i;

  errno = 0;

  if( nb != NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for exone, inc, r . ********************/
  exone = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !exone )
  {
    /* fatal error */
    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE exone *************/
    __mpu_sbrk( -(int)(ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  r = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !r )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(2*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  he = (__mpu_uint16_t *)ee;
  ei_cleaz( ei, nb ); /* clear out exploded internal
                         e-type real number. */

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  ++he; /* point to high __mpu_uint16_t */
#endif


#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* hight part */
  p = inc;
  for( i = 0; i < ne - 1; i++ ) *p++ = (EMUSHORT)0;
  *p = (EMUSHORT)0x7f;

  p = exone;
  *p++ = HIGHT_EXONE; /* 0x3fff... */
  for( i = 0; i < ne - 1; i++ ) *p++ = MASK_ALL_BITS;

  p = r;
  for( i = 0; i < ne - 1; i++ ) *p++ = (EMUSHORT)0;
  *p = (EMUSHORT)(*he);
#else
  /* hight part */
  p = inc + ne - 1;
  for( i = 0; i < ne - 1; i++ ) *p-- = (EMUSHORT)0;
  *p = (EMUSHORT)0x7f;

  p = exone + ne - 1;
  *p-- = HIGHT_EXONE;
  for( i = 0; i < ne - 1; i++ ) *p-- = MASK_ALL_BITS;

  p = r + ne - 1;
  for( i = 0; i < ne - 1; i++ ) *p-- = (EMUSHORT)0;
  *p = (EMUSHORT)(*he);
#endif


  /* Sign */
  if( *he & 0x8000 )
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  *ei = MASK_ALL_BITS;
#else
  *(ei + np - 1) = MASK_ALL_BITS;
#endif

  /* hgw */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei[ne + 1] = (EMUSHORT)((*he & 0x7f) | 0x80);
#else
  ei[ns + 1] = (EMUSHORT)((*he & 0x7f) | 0x80);
#endif

  /* Skip Sign and 7 significand bits */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  *(r + ne - 1) &= (EMUSHORT)0x7f80; /* т.е. (~0x807f) */
#else
  *r &= (EMUSHORT)0x7f80; /* т.е. (~0x807f) */
#endif

  /****************
    INFINITY
   ****************/
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  if( *(r + ne - 1) == 0x7f80 )
#else
  if( *r == 0x7f80 )
#endif
  {
    /********
      NANS
     ********/
    /* indeterminacy */
    if( e_isind( ee, nb ) )
    {
      ei_ind( ei, nb );

      /* FREE exone *************/
      /* FREE inc ***************/
      /* FREE r *****************/
      __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }
    /* nanmin */
    if( e_isnanmin( ee, nb ) )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      ei_nanmin( ei, ei[0] != (EMUSHORT)0, nb );
#else
      ei_nanmin( ei, ei[ns + ne + 2] != (EMUSHORT)0, nb );
#endif

      /* FREE exone *************/
      /* FREE inc ***************/
      /* FREE r *****************/
      __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }
    /* nanmax */
    if( e_isnanmax( ee, nb ) )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      ei_nanmax( ei, ei[0] != (EMUSHORT)0, nb );
#else
      ei_nanmax( ei, ei[ns + ne + 2] != (EMUSHORT)0, nb );
#endif

      /* FREE exone *************/
      /* FREE inc ***************/
      /* FREE r *****************/
      __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }
    /* nans */
    if( e_isnans( ee, nb ) )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      ei_nan( ei, ei[0] != (EMUSHORT)0, nb );
#else
      ei_nan( ei, ei[ns + ne + 2] != (EMUSHORT)0, nb );
#endif

      /* FREE exone *************/
      /* FREE inc ***************/
      /* FREE r *****************/
      __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }
    /**********
      END NANS
     **********/

    ei_cleazs( ei, nb ); /* не трогать знак */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    ei_infin( ei, ei[0] != (EMUSHORT)0, nb );
#else
    ei_infin( ei, ei[ns + ne + 2] != (EMUSHORT)0, nb );
#endif

    /* FREE exone *************/
    /* FREE inc ***************/
    /* FREE r *****************/
    __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /**************
    END INFINITY
   **************/

  ei_shrn( r, r, 7, ne );


  /* If zero Exponent, then the Significand is denormalized.
    So take back the understood high Significand bit. */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  if( *(r + ne - 1) == 0 )
#else
  if( *r == 0 )
#endif
  {
    denorm = 1;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    ei[ne + 1] &= ~((EMUSHORT)0x80);
#else
    ei[ns + 1] &= ~((EMUSHORT)0x80);
#endif
  }

  ei_sube( exone, exone,   inc, ne );
  ei_adde(     r,     r, exone, ne );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( &ei[1],    r, ne, ne );
#else
  ei_cpye_unpack( &ei[ns+2], r, ne, ne );
#endif

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  pe = (__mpu_uint16_t *)&ei[ne + 2];
  /* NOTE: I not TEST !!! */
  *pe = *(he + 1);
/* продолжение для e53
  *(++pe) = *(he + 2);
  *(++pe) = *(he + 3);
 */
#else
  pe = (__mpu_uint16_t *)&ei[ns];
  /* следующий оператор требуется только здесь */
  pe += (BITS_PER_EMUSHORT - 16) / 16;
  *pe = *(he - 1);
/* продолжение для e53
  *(--pe) = *(he - 2);
  *(--pe) = *(he - 3);
 */
#endif

  ei_shift( ei, -8, nb ); /* `-' - down(right) */

  if( denorm )
  {
    /* if zero Exponent, then normalize the Significand */
    if( (k = ei_normalize(ei, nb)) > (__mpu_int32_t)EINSBITS(nb) )
      ei_cleazs( ei, nb );
    else
    {
      /* Exponent -= (k - 1); */
      k -= 1;
      ei_cvte_unpack( inc, (EMUSHORT *)&k, ne, 1 );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      p = &ei[1];
#else
      p = &ei[ns+2];
#endif
      ei_sube( p, p, inc, ne );
    }
  } /* End if( denorm ) */


  /* FREE exone *************/
  /* FREE inc ***************/
  /* FREE r *****************/
  __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of unpack_32() */

static void unpack_64( EMUSHORT *ei, EMUSHORT *ee, int nb )
/***************************************************************

 Description        : unpack_64() Распаковывает real64 data
                                  struct в internal e-type data
                                  struct.

 Concepts           :

 NOTE               : Функция работает правильно только для
                      размеров EMUSHORT кратных 16 бит
                      (16,32,48,64,80,96,...).
                      SEE operator:

                        pe += (BITS_PER_EMUSHORT - 16) / 16

                      in LITTLE_ENDIAN case.

 Use Global Variable:

 Use Functions      : 

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                                      память под нее
                                      выделяется до
                                      применения
                                      unpack_32() и
                                      ее размер на
                                      совести
                                      программиста;
                      EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void];

 ***************************************************************/
{
  EMUSHORT    *exone = NULL,
                *inc = NULL,
                  *r = NULL;
  EMUSHORT        *p;
  __mpu_uint16_t  *he, *pe;
  int              denorm = 0;
  __mpu_int32_t    k;
  int              np, ne, ns, i;

  errno = 0;

  if( nb != NBR_64 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for exone, inc, r . ********************/
  exone = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !exone )
  {
    /* fatal error */
    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE exone *************/
    __mpu_sbrk( -(int)(ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  r = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !r )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(2*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  he = (__mpu_uint16_t *)ee;
  ei_cleaz( ei, nb ); /* clear out exploded internal
                         e-type real number. */

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  he += 3; /* point to high word16bits */
#endif


#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* hight part */
  p = inc;
  for( i = 0; i < ne - 1; i++ ) *p++ = (EMUSHORT)0;
  *p = (EMUSHORT)0x3ff;

  p = exone;
  *p++ = HIGHT_EXONE; /* 0x3fff... */
  for( i = 0; i < ne - 1; i++ ) *p++ = MASK_ALL_BITS;

  p = r;
  for( i = 0; i < ne - 1; i++ ) *p++ = (EMUSHORT)0;
  *p = (EMUSHORT)(*he);
#else
  /* hight part */
  p = inc + ne - 1;
  for( i = 0; i < ne - 1; i++ ) *p-- = (EMUSHORT)0;
  *p = (EMUSHORT)0x3ff;

  p = exone + ne - 1;
  *p-- = HIGHT_EXONE;
  for( i = 0; i < ne - 1; i++ ) *p-- = MASK_ALL_BITS;

  p = r + ne - 1;
  for( i = 0; i < ne - 1; i++ ) *p-- = (EMUSHORT)0;
  *p = (EMUSHORT)(*he);
#endif


  /* Sign */
  if( *he & 0x8000 )
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  *ei = MASK_ALL_BITS;
#else
  *(ei + np - 1) = MASK_ALL_BITS;
#endif

  /* hgw */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei[ne + 1] = (EMUSHORT)((*he & 0x0f) | 0x10);
#else
  ei[ns + 1] = (EMUSHORT)((*he & 0x0f) | 0x10);
#endif

  /* Skip Sign and 7 significand bits */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  *(r + ne - 1) &= (EMUSHORT)0x7ff0; /* т.е. (~0x800f) */
#else
  *r &= (EMUSHORT)0x7ff0; /* т.е. (~0x800f) */
#endif

  /****************
    INFINITY
   ****************/
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  if( *(r + ne - 1) == 0x7ff0 )
#else
  if( *r == 0x7ff0 )
#endif
  {
    /********
      NANS
     ********/
    /* indeterminacy */
    if( e_isind( ee, nb ) )
    {
      ei_ind( ei, nb );

      /* FREE exone *************/
      /* FREE inc ***************/
      /* FREE r *****************/
      __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }
    /* nanmin */
    if( e_isnanmin( ee, nb ) )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      ei_nanmin( ei, ei[0] != (EMUSHORT)0, nb );
#else
      ei_nanmin( ei, ei[ns + ne + 2] != (EMUSHORT)0, nb );
#endif

      /* FREE exone *************/
      /* FREE inc ***************/
      /* FREE r *****************/
      __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }
    /* nanmax */
    if( e_isnanmax( ee, nb ) )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      ei_nanmax( ei, ei[0] != (EMUSHORT)0, nb );
#else
      ei_nanmax( ei, ei[ns + ne + 2] != (EMUSHORT)0, nb );
#endif

      /* FREE exone *************/
      /* FREE inc ***************/
      /* FREE r *****************/
      __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }
    /* nans */
    if( e_isnans( ee, nb ) )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      ei_nan( ei, ei[0] != (EMUSHORT)0, nb );
#else
      ei_nan( ei, ei[ns + ne + 2] != (EMUSHORT)0, nb );
#endif

      /* FREE exone *************/
      /* FREE inc ***************/
      /* FREE r *****************/
      __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }
    /**********
      END NANS
     **********/

    ei_cleazs( ei, nb ); /* не трогать знак */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    ei_infin( ei, ei[0] != (EMUSHORT)0, nb );
#else
    ei_infin( ei, ei[ns + ne + 2] != (EMUSHORT)0, nb );
#endif

    /* FREE exone *************/
    /* FREE inc ***************/
    /* FREE r *****************/
      __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /**************
    END INFINITY
   **************/

  ei_shrn( r, r, 4, ne );


  /* If zero Exponent, then the Significand is denormalized.
    So take back the understood high Significand bit. */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  if( *(r + ne - 1) == 0 )
#else
  if( *r == 0 )
#endif
  {
    denorm = 1;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    ei[ne + 1] &= ~((EMUSHORT)0x10);
#else
    ei[ns + 1] &= ~((EMUSHORT)0x10);
#endif
  }

  ei_sube( exone, exone,   inc, ne );
  ei_adde(     r,     r, exone, ne );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( &ei[1],    r, ne, ne );
#else
  ei_cpye_unpack( &ei[ns+2], r, ne, ne );
#endif

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  pe = (__mpu_uint16_t *)&ei[ne + 2];
  /* NOTE: I not TEST !!! */
  *pe = *(he + 1);
  *(++pe) = *(he + 2);
  *(++pe) = *(he + 3);
#else
  pe = (__mpu_uint16_t *)&ei[ns];
  /* следующий оператор требуется только здесь */
  pe += (BITS_PER_EMUSHORT - 16) / 16;
  *pe = *(he - 1);
  *(--pe) = *(he - 2);
  *(--pe) = *(he - 3);
#endif

  ei_shift( ei, -5, nb ); /* `-' - down(right) */

  if( denorm )
  {
    /* if zero Exponent, then normalize the Significand */
    if( (k = ei_normalize(ei, nb)) > (__mpu_int32_t)EINSBITS(nb) )
      ei_cleazs( ei, nb );
    else
    {
      /* Exponent -= (k - 1); */
      k -= 1;
      ei_cvte_unpack( inc, (EMUSHORT *)&k, ne, 1 );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      p = &ei[1];
#else
      p = &ei[ns+2];
#endif
      ei_sube( p, p, inc, ne );
    }

  } /* End if( denorm ) */

  /* FREE exone *************/
  /* FREE inc ***************/
  /* FREE r *****************/
  __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of unpack_64() */


/***************************************************************
  NOTE:

     EMUPART <= EMUSHORT всегда.
     На данный момент мы используем размер в 32 бита как для
     EMUSHORT, так и для EMUPART по тому, что работаем с
     моделями ILP32, LP64 для машин с разрядностью до 64 бит.
     В случаее 128-разрядных машин, следует сохранить размер
     EMUPART в 32 бита, а размер EMUSHORT может быть 64 бита.
 ***************************************************************/

static void unpack_np( EMUSHORT *ei, EMUSHORT *ee, int nb )
/***************************************************************

 Description        : unpack_np() Распаковывает все начиная с
                                  real128 (real128,...) data
                                  struct в internal e-type
                                  data struct.

 Concepts           :

 NOTE               :
                      Функция работает правильно только для
                      размеров EMUSHORT кратных
                      BITS_PER_EMUPART(16|32) бит.
                      SEE:

                     (BITS_PER_EMUSHORT - BITS_PER_EMUPART)
               p += ----------------------------------------;
                             BITS_PER_EMUPART;


 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                                      память под нее
                                      выделяется до
                                      применения
                                      unpack_128() и
                                      ее размер на
                                      совести
                                      программиста;
                      EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void];

 ***************************************************************/
{
  EMUSHORT   *exone = NULL,
               *inc = NULL,
                 *r = NULL;
  EMUSHORT       *p;
  EMUPART        *he, *pe;
  int             denorm = 0;
  __mpu_int32_t   k;
  int             np, ne, ns, nex, nsx, i;

  if( nb < NBR_128 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for exone, inc, r . ********************/
  exone = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !exone )
  {
    /* fatal error */
    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE exone *************/
    __mpu_sbrk( -(int)(ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  r = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !r )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(2*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  nex = EMUPARTSIZE(NEBITS(nb));
  nsx = EMUPARTSIZE(NSBITS(nb));

  he = (EMUPART *)ee;
  ei_cleaz( ei, nb ); /* clear out exploded internal
                         e-type real number. */

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  he += nex - 1; /* point to low EMUPART of Exponent */
#else
  he += nsx;     /* point to low EMUPART of Exponent */
#endif

  /* inc используется для хранения EXONE исходного формата */
  /*
    но до ее основного применения она используется для:
    1) проверки всех бит исходной экспоненты на 1;
    2) проверки всех бит исходной экспоненты на 0;
   */
  for( i = 0; i < ne; i++ ) inc[i] = (EMUSHORT)0;
  for( i = 0; i < ne; i++ )   r[i] = (EMUSHORT)0;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* исходный формат EXONE */
  /* low part */
  pe = (EMUPART *)(inc + ne - 1);
  pe += (BITS_PER_EMUSHORT - BITS_PER_EMUPART) /
    /* -------------------------------------- */
                 BITS_PER_EMUPART;
  for( i = 0; i < nex - 1; i++ ) *pe-- = PART_MASK_ALL_BITS;
  *pe = PART_HIGHT_EXP;

  /* целевой формат EXONE */
  /* hight part */
  p = exone;
  *p++ = HIGHT_EXONE; /* 0x3fff... */
  for( i = 0; i < ne - 1; i++ ) *p++ = MASK_ALL_BITS;

  /* Copy Exponent */
  /* low part */
  pe = (EMUPART *)(r + ne - 1);
  pe += (BITS_PER_EMUSHORT - BITS_PER_EMUPART) /
    /* -------------------------------------- */
                 BITS_PER_EMUPART;
  for( i = 0; i < nex - 1; i++ ) *pe-- = *he--;
  *pe = *he;
#else
  /* исходный формат EXONE */
  /* low part */
  pe = (EMUPART *)inc;
  for( i = 0; i < nex - 1; i++ ) *pe++ = PART_MASK_ALL_BITS;
  *pe = PART_HIGHT_EXP;

  /* целевой формат EXONE */
  /* hight part */
  p = exone + ne - 1;
  *p-- = HIGHT_EXONE;
  for( i = 0; i < ne - 1; i++ ) *p-- = MASK_ALL_BITS;

  /* Copy Exponent */
  /* low part */
  pe = (EMUPART *)r;
  for( i = 0; i < nex - 1; i++ ) *pe++ = *he++;
  *pe = *he;
#endif
  /* NOW *he point to hight EMUPART of Exponent in the source format */
  /* NOW *pe point to hight EMUPART of Exponent in the target (r)    */

  /* Sign */
  if( *he & PART_MASK_SIGN )
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  *ei = MASK_ALL_BITS;
#else
  *(ei + np - 1) = MASK_ALL_BITS;
#endif

  /* hgw */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei[ne + 1] = (EMUSHORT)1;
#else
  ei[ns + 1] = (EMUSHORT)1;
#endif

  /* Skip Sign */
  *pe &= PART_HIGHT_EXP;


  /****************
    INFINITY
   ****************/

  if( ei_cmpe( r, inc, ne ) == 0 ) /* r == inc */
  {
    /********
      NANS
     ********/
    /* indeterminacy */
    if( e_isind( ee, nb ) )
    {
      ei_ind( ei, nb );

      /* FREE exone *************/
      /* FREE inc ***************/
      /* FREE r *****************/
      __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }
    /* nanmin */
    if( e_isnanmin( ee, nb ) )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      ei_nanmin( ei, ei[0] != (EMUSHORT)0, nb );
#else
      ei_nanmin( ei, ei[ns + ne + 2] != (EMUSHORT)0, nb );
#endif

      /* FREE exone *************/
      /* FREE inc ***************/
      /* FREE r *****************/
      __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }
    /* nanmax */
    if( e_isnanmax( ee, nb ) )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      ei_nanmax( ei, ei[0] != (EMUSHORT)0, nb );
#else
      ei_nanmax( ei, ei[ns + ne + 2] != (EMUSHORT)0, nb );
#endif

      /* FREE exone *************/
      /* FREE inc ***************/
      /* FREE r *****************/
      __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }
    /* nans */
    if( e_isnans( ee, nb ) )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      ei_nan( ei, ei[0] != (EMUSHORT)0, nb );
#else
      ei_nan( ei, ei[ns + ne + 2] != (EMUSHORT)0, nb );
#endif

      /* FREE exone *************/
      /* FREE inc ***************/
      /* FREE r *****************/
      __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }
    /**********
      END NANS
     **********/

    ei_cleazs( ei, nb ); /* не трогать знак */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    ei_infin( ei, ei[0] != (EMUSHORT)0, nb );
#else
    ei_infin( ei, ei[ns + ne + 2] != (EMUSHORT)0, nb );
#endif

    /* FREE exone *************/
    /* FREE inc ***************/
    /* FREE r *****************/
    __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /**************
    END INFINITY
   **************/


  /* If zero Exponent, then the Significand is denormalized.
    So take back the understood high Significand bit. */
  for( i = 0; i < ne; i++ ) inc[i] = (EMUSHORT)0;
  if( ei_cmpe( r, inc, ne ) == 0 ) /* r == inc (inc = 0) */
  {
    denorm = 1;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    ei[ne + 1] = (EMUSHORT)0;
#else
    ei[ns + 1] = (EMUSHORT)0;
#endif
  }

  /* Create EXONE of source format */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* исходный формат EXONE */
  /* low part */
  pe = (EMUPART *)(inc + ne - 1);
  pe += (BITS_PER_EMUSHORT - BITS_PER_EMUPART) /
    /* -------------------------------------- */
                 BITS_PER_EMUPART;
  for( i = 0; i < nex - 1; i++ ) *pe-- = PART_MASK_ALL_BITS;
  *pe = PART_HIGHT_EXONE;
#else
  /* исходный формат EXONE */
  /* low part */
  pe = (EMUPART *)inc;
  for( i = 0; i < nex - 1; i++ ) *pe++ = PART_MASK_ALL_BITS;
  *pe = PART_HIGHT_EXONE;
#endif

  /* r += EXONEtarget - EXONEsource */
  ei_sube( exone, exone,   inc, ne );
  ei_adde(     r,     r, exone, ne );
  /* Copy Exponent */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( &ei[1],    r, ne, ne );
#else
  ei_cpye_unpack( &ei[ns+2], r, ne, ne );
#endif

  /* Copy Significand */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  pe = (EMUPART *)&ei[ne + 2];
  he = (EMUPART *)&ee[nex];
  /* NOTE: I not TEST !!! */
  for( i = 0; i < nsx; i++ ) *pe++ = *he++;
#else
  pe = (EMUPART *)&ei[ns];
  he = (EMUPART *)&ee[ns-1];
  /* следующий оператор требуется только здесь */
  pe += (BITS_PER_EMUSHORT - BITS_PER_EMUPART) /
    /* -------------------------------------- */
                 BITS_PER_EMUPART;
  he += (BITS_PER_EMUSHORT - BITS_PER_EMUPART) /
    /* -------------------------------------- */
                 BITS_PER_EMUPART;
  for( i = 0; i < nsx; i++ ) *pe-- = *he--;
#endif

  ei_shift( ei, -1, nb ); /* `-' - down(right) */

  if( denorm )
  {
    /* if zero Exponent, then normalize the Significand */
    if( (k = ei_normalize(ei, nb)) > (__mpu_int32_t)EINSBITS(nb) )
      ei_cleazs( ei, nb );
    else
    {
      /* Exponent -= (k - 1); */
      k -= 1;
      ei_cvte_unpack( inc, (EMUSHORT *)&k, ne, 1 );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      p = &ei[1];
#else
      p = &ei[ns+2];
#endif
      ei_sube( p, p, inc, ne );
    }

  } /* End if( denorm ) */

  /* FREE exone *************/
  /* FREE inc ***************/
  /* FREE r *****************/
  __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of unpack_np() */


void unpack( EMUSHORT *ei, EMUSHORT *ee, int nb )
/***************************************************************

 Description        : unpack() Распаковывает `real<all>' data
                               struct в internal e-type data
                               struct.

 Concepts           :

 Use Global Variable:

 Use Functions      :
                      unpack_32 ( *ei, *ee, nb ); | this file
                      unpack_64 ( *ei, *ee, nb ); | this file
                      unpack_np ( *ei, *ee, nb ); | this file

 Parameters         : EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                                      память под нее
                                      выделяется до
                                      применения
                                      unpack() и
                                      ее размер на
                                      совести
                                      программиста;
                      EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void];

 ***************************************************************/
{
  EMUSHORT *ex = NULL;  /* External format */
  int       np;

  if( nb < NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  /*
    NP in EMUPARTs.
    BITS_PER_EMUPART == only(16 || 32).
   */
  np = nb/(BITS_PER_EMUPART);

  /*** Allocate memory for ex . *******************************/
  ex = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUPART) );
  if( !ex )
  {
    /* fatal error */
    return;
  }
  /************************************************************/

  /* copy EE to EX (External format) */
  (void)memcpy( (void *)ex, (void *)ee, (size_t)(np*SIZE_OF_EMUPART) );

  switch( nb )
  {
    case NBR_32    :
      unpack_32( ei, ex, nb );
      break;
    case NBR_64    :
      unpack_64( ei, ex, nb );
      break;
    case NBR_128   :
    case NBR_256   :
    case NBR_512   :
    case NBR_1024  :
    case NBR_2048  :
    case NBR_4096  :
    case NBR_8192  :
    case NBR_16384 :
    case NBR_32768 :
    case NBR_65536 :
    case NBR_131072:
      unpack_np( ei, ex, nb );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

  /* FREE ex ****************/
  __mpu_sbrk( -(int)(np*SIZE_OF_EMUPART) );
  /**************************/

  return;

} /* End of unpack() */


int ei_cmpm( EMUSHORT *ai, EMUSHORT *bi, int nb )
/***************************************************************

 Description        : ei_cmpm() Compare Significands of numbers
                                in internal e-type data struct.

 Concepts           : Guard words are included in the
                      comparison.

 Use Global Variable:

 Use Functions      :
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *ai; - указатель на
                                      internal e-type
                                      data struct;
                      EMUSHORT *bi; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc;       - Result of Comparison.

                      if( ai  > bi )  rc = +1;
                      if( ai == bi )  rc =  0;
                      if( ai  < bi )  rc = -1;

 ***************************************************************/
{
  EMUSHORT *x, *y;
  int       ne, ns, hgw, i;

  if( nb < NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return( 0 );
  }

  ne = internal_ne( nb );
  ns = internal_ns( nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  hgw = ne + 1;
#else
  hgw = ns + 1;
#endif

  x = &ai[hgw];
  y = &bi[hgw];

  for( i = 0; i < ns + 2; i++ )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    if( *x++ != *y++ )
#else
    if( *x-- != *y-- )
#endif
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      if( *(--x) > *(--y) )
#else
      if( *(++x) > *(++y) )
#endif
        return( 1 );
      else
        return( -1 );

    } /* End if( != ) */

  } /* End for( i = 0; i < ns+2; i++ ) */

  return( 0 );

} /* End of ei_cmpm() */

void ei_addm( EMUSHORT *ci, EMUSHORT *ai, EMUSHORT *bi, int nb )
/***************************************************************

 Description        : ei_addm() Add Significands of e-type AI
                                and BI.  AI + BI replaces CI.

 Concepts           : Guard words are included in the Add.
                      CI может указывать на любое число,
                      даже на AI или BI.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *ci; - Result;
                      EMUSHORT *ai; - указатель на
                                      internal e-type
                                      data struct;
                      EMUSHORT *bi; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void].

 ***************************************************************/
{
  EMULONG   rc, carry = 0;
  EMUSHORT *z, *x, *y;
  int       np, ns, i;

  if( nb < NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  np = internal_np( nb );
  ns = internal_ns( nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* point to lgw */
  x = ai + np - 1;
  y = bi + np - 1;
  z = ci + np - 1;
#else
  /* point to lgw */
  x = ai;
  y = bi;
  z = ci;
#endif

  for( i = 0; i < ns + 2; i++ )
  {
    rc = (EMULONG)(*x) + (EMULONG)(*y) + carry;

    if( rc & MASK_CARRY ) carry = 1;
    else                  carry = 0;

    *z = (EMUSHORT)rc;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    --x;
    --y;
    --z;
#else
    ++x;
    ++y;
    ++z;
#endif

  } /* End for( i = 0; i < ns + 2; i++ ) */

} /* End of ei_addm() */

void ei_subm( EMUSHORT *ci, EMUSHORT *ai, EMUSHORT *bi, int nb )
/***************************************************************

 Description        : ei_subm() Subtract Significands of e-type
                                AI and BI. AI - BI replaces CI.

 Concepts           : Guard words are included in the
                      Subtraction. CI может указывать на любое
                      число, даже на AI или BI.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *ci; - Result;
                      EMUSHORT *ai; - указатель на
                                      internal e-type
                                      data struct;
                      EMUSHORT *bi; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                     data struct.

 Return             : [void].

 ***************************************************************/
{
  EMULONG   rc, carry = 0;
  EMUSHORT *z, *x, *y;
  int       np, ns, i;

  if( nb < NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  np = internal_np( nb );
  ns = internal_ns( nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* point to lgw */
  x = ai + np - 1;
  y = bi + np - 1;
  z = ci + np - 1;
#else
  /* point to lgw */
  x = ai;
  y = bi;
  z = ci;
#endif

  for( i = 0; i < ns + 2; i++ )
  {
    rc = (EMULONG)(*x) - (EMULONG)(*y) - carry;

    if( rc & MASK_CARRY ) carry = 1;
    else                  carry = 0;

    *z = (EMUSHORT)rc;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    --x;
    --y;
    --z;
#else
    ++x;
    ++y;
    ++z;
#endif

  } /* End for( i = 0; i < ns + 2; i++ ) */

} /* End of ei_subm() */



/***************************************************************
   Radix MAX[unsigned EMUSHORT] versions of multiply and divide.
   if HOST_BITS_PER_EMUSHORT == 16(от 0 до 65 535),
      then Radix = 65 536;
   if HOST_BITS_PER_EMUSHORT == 32(от 0 до 4 294 967 295),
      then Radix = 4 294 967 296;
   if HOST_BITS_PER_EMUSHORT == 64(от 0 до 18 446 744 073 709 551 616),
      then Radix = 18 446 744 073 709 551 616;
   etc.
 ***************************************************************/

static void mEMUSHORTm( EMUSHORT *prodi, EMUSHORT *numi, EMUSHORT mul, int nb )
/************************************************
   Multiply significand of e-type number NUMI
   by BITS_PER_EMUSHORT-bit quantity MUL,
   return e-type result to PRODI.
   ВОЗМОЖНО ИСПОЛЬЗОВАНИЕ mEMUSHORTm(X,X,a,nb):
   т.е. результат можно поместить на место
   операнда NUMI.
 ************************************************/
{
  EMUSHORT  *pp;
  EMULONG    carry;
  EMUSHORT  *prod = NULL;
  EMUSHORT  *ps;
  EMULONG    a, m;
  int        i, np, ne, ns;

  if( nb < NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for prod . *****************************/
  prod = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !prod )
  {
    /* fatal error */
    return;
  }
  /************************************************************/

  a = mul;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* low part of Significand */
  pp = &prod[np - 2];
  *pp++ = (EMUSHORT)0;
  /* lgw */
  ps = &numi[np - 1];
#else
  /* low part of Significand */
  pp = &prod[1];
  *pp-- = (EMUSHORT)0;
  /* lgw */
  ps = &numi[0];
#endif
  *pp = (EMUSHORT)0;

  for( i = 0; i < ns + 1; i++ )
  {
    if( *ps == (EMUSHORT)0 )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      --ps;
      --pp;
      *(pp-1) = (EMUSHORT)0;
#else
      ++ps;
      ++pp;
      *(pp+1) = (EMUSHORT)0;
#endif
    }
    else
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      m = (EMULONG) a * *ps--;
#else
      m = (EMULONG) a * *ps++;
#endif
      carry = (m & MASK_ALL_BITS) + *pp;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      *pp-- = (EMUSHORT)carry;
#else
      *pp++ = (EMUSHORT)carry;
#endif

      carry = (carry >> BITS_PER_EMUSHORT) + (m >> BITS_PER_EMUSHORT) + *pp;

      *pp = (EMUSHORT)carry;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      *(pp-1) = (EMUSHORT)(carry >> BITS_PER_EMUSHORT);
#else
      *(pp+1) = (EMUSHORT)(carry >> BITS_PER_EMUSHORT);
#endif
    }

  } /* End for( i = 0; i < ns + 1; i++ ) */

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  for( i = ne + 1; i < np; i++ ) 
#else
  for( i = 0; i < ns + 2; i++ ) 
#endif
    prodi[i] = prod[i];

  /* FREE prod **************/
  __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of mEMUSHORTm() */


int ei_divm( EMUSHORT *quoti, EMUSHORT *numi, EMUSHORT *deni, int nb )
/***************************************************************

 Description        : ei_divm() Divide Significands of e-type
                                NUMI and DENI. NUMI / DENI
                                replaces QUOTI.

 Concepts           : Sign and Exponent of NUMI replaces Sign
                      and Exponent of QUOTI(NUMI[Sign,Exp] ->
                      QUOTI[Sign,Exp]).
                      QUOTI может указывать на любое число,
                      даже на NUMI или DENI.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *quoti; - Result;
                      EMUSHORT *numi;  - указатель на
                                         internal e-type
                                         data struct -
                                         ДЕЛИМОЕ;
                      EMUSHORT *deni;  - указатель на
                                         internal e-type
                                         data struct -
                                         ДЕЛИТЕЛЬ;
                      int nb;          - количество бит в
                                         external e-type
                                         data struct.

 Return             : int j;           - признак наличия
                                         остатка от
                                         деления;
                      if( remainder != 0 ) j = 1;
                      if( remainder == 0 ) j = 0;

                      if( error ) j = -1;

 ***************************************************************/
{
  EMUSHORT  *pcpy_num = NULL,
            *pcpy_den = NULL,
               *tprod = NULL;
  EMUSHORT  *p, *q;
  EMULONG    tnum;
  EMUSHORT   j, tdenm, tquot;
  int        i, np, ne, ns;

  if( nb < NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return( -1 );
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for pcpy_num, pcpy_den, tprod . ********/
  pcpy_num = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !pcpy_num )
  {
    /* fatal error */
    return( -1 );
  }

  pcpy_den = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !pcpy_den )
  {
    /* fatal error */

    /* FREE pcpy_num **********/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    return( -1 );
  }

  tprod = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !tprod )
  {
    /* fatal error */

    /* FREE pcpy_num **********/
    /* FREE pcpy_den **********/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return( -1 );
  }
  /************************************************************/

  /* Copy NUM */
  p = numi;
  q = pcpy_num;
  for( i = 0; i < np; i++ ) *q++ = *p++;

  /* Copy DEN */
  p = deni;
  q = pcpy_den;
  for( i = 0; i < np; i++ ) *q++ = *p++;

  ei_cleaz( quoti, nb ); /* clear out exploded internal
                            e-type real number. */

  /* Copy Sign & Exponent */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
   /* hight part */
   p = pcpy_num;
   q = quoti;
   for( i = 0; i < ne + 1; i++ ) *q++ = *p++;
#else
   /* hight part */
   p = pcpy_num + np - 1;
   q = quoti    + np - 1;
   for( i = 0; i < ne + 1; i++ ) *q-- = *p--;
#endif

   ei_shdown( pcpy_num, (unsigned)1, nb );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
   tdenm = pcpy_den[ne + 2];
   q = &quoti[nE + 1]; /* hgw */
#else
   tdenm = pcpy_den[ns];
   q = &quoti[ns + 1]; /* hgw */
#endif

   for( i = 0; i < ns + 2; i++ )
   {
     /* Find trial quotient digit (the radix ...). */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
     tnum = (((EMULONG)pcpy_num[ne + 1]) << BITS_PER_EMUSHORT) + pcpy_num[ne + 2];
#else
     tnum = (((EMULONG)pcpy_num[ns + 1]) << BITS_PER_EMUSHORT) + pcpy_num[ns];
#endif
     /* Do not execute the divide instruction if it will overflow. */
     if( ((EMULONG)tdenm * MASK_ALL_BITS) < tnum )
       tquot = MASK_ALL_BITS;
     else
       tquot = (EMUSHORT)(tnum / tdenm);

     /* Multiply denominator by trial quotient digit. */
     mEMUSHORTm( tprod, pcpy_den, tquot, nb );

     /* The quotient digit may have been over estimated. */
     if( ei_cmpm( tprod, pcpy_num, nb ) > 0 )
     {
       tquot -= 1;
       ei_subm( tprod, tprod, pcpy_den, nb );
       if( ei_cmpm( tprod, pcpy_num, nb ) > 0 )
       {
         tquot -= 1;
         ei_subm( tprod, tprod, pcpy_den, nb );
       }
     }
     ei_subm( pcpy_num, pcpy_num, tprod, nb );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
     *q++ = tquot;
#else
     *q-- = tquot;
#endif
     ei_shup( pcpy_num, (unsigned)BITS_PER_EMUSHORT, nb );
  }

  /* test for nonzero remainder after roundoff bit */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* Set pointer to hgw */
  p = &pcpy_num[ne + 1]; 
#else
  /* Set pointer to hgw */
  p = &pcpy_num[ns + 1];
#endif
  j = (EMUSHORT)0;
  for( i = 0; i < ns + 2; i++ )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    j |= *p++;
#else
    j |= *p--;
#endif
  }

  if( j ) j = (EMUSHORT)1;

  /* FREE pcpy_num **********/
  /* FREE pcpy_den **********/
  /* FREE tprod *************/
  __mpu_sbrk( -(int)(3*np*SIZE_OF_EMUSHORT) );
  /**************************/

  return( (int)j );

} /* End of ei_divm() */

int ei_mulm( EMUSHORT *prodi, EMUSHORT *numi, EMUSHORT *muli, int nb )
/***************************************************************

 Description        : ei_mulm() Multiply Significands of e-type
                                NUMI and MULI. NUMI * MULI
                                replaces PRODI.

 Concepts           : Sign and Exponent of NUMI replaces Sign
                      and Exponent of PRODI(NUMI[Sign,Exp] ->
                      PRODI[Sign,Exp]).
                      PRODI может указывать на любое число,
                      даже на NUMI или MULI.
                      МАНТИССА МНОЖИТЕЛЯ НЕ МОЖЕТ БЫТЬ РАВНА
                      НУЛЮ.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *prodi; - Result;
                      EMUSHORT *numi;  - указатель на
                                         internal e-type
                                         data struct -
                                         МНОЖИМОЕ;
                      EMUSHORT *muli;  - указатель на
                                         internal e-type
                                         data struct -
                                         МНОЖИТЕЛЬ;
                      int nb;          - количество бит в
                                         external e-type
                                         data struct.

 Return             : int j;           - флаг потерянных
                                         ненулевых бит;

                      if( lost nonzero bits != 0 ) j = 1;
                      if( lost nonzero bits == 0 ) j = 0;

                      if( error ) j = -1;

 ***************************************************************/
{
  EMUSHORT  *pcpy_num = NULL,
            *pcpy_mul = NULL,
               *tprod = NULL;
  EMUSHORT  *p, *q;
  EMUSHORT   j;
  int        i, np, ne, ns;

  if( nb < NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return( -1 );
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for pcpy_num, pcpy_mul, tprod . ********/
  pcpy_num = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !pcpy_num )
  {
    /* fatal error */
    return( -1 );
  }

  pcpy_mul = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !pcpy_mul )
  {
    /* fatal error */

    /* FREE pcpy_num **********/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    return( -1 );
  }

  tprod = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !tprod )
  {
    /* fatal error */

    /* FREE pcpy_num **********/
    /* FREE pcpy_mul **********/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return( -1 );
  }
  /************************************************************/

  /* Copy NUM */
  p = numi;
  q = pcpy_num;
  for( i = 0; i < np; i++ ) *q++ = *p++;

  /* Copy MUL */
  p = muli;
  q = pcpy_mul;
  for( i = 0; i < np; i++ ) *q++ = *p++;

  ei_cleaz( prodi, nb ); /* clear out exploded internal
                            e-type real number. */

  /* Copy Sign & Exponent */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* hight part */
  p = pcpy_num;
  q = prodi;
  for( i = 0; i < ne + 1; i++ ) *q++ = *p++;
#else
  /* hight part */
  p = pcpy_num + np - 1;
  q = prodi    + np - 1;
  for( i = 0; i < ne + 1; i++ ) *q-- = *p--;
#endif

  j = (EMUSHORT)0;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* lgw */
  p = &pcpy_mul[np - 1];
  q = &prodi[np - 1];
#else
  /* lgw */
  p = &pcpy_mul[0];
  q = &prodi[0];
#endif

  for( i = 0; i < ns + 1; i++ )
  {
    if( *p == (EMUSHORT)0 )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      --p;
#else
      ++p;
#endif
    }
    else
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      mEMUSHORTm( tprod, pcpy_num, *p--, nb );
#else
      mEMUSHORTm( tprod, pcpy_num, *p++, nb );
#endif
      ei_addm( prodi, prodi, tprod, nb );
    }
    j |= *q;
    ei_shdown( prodi, (unsigned)BITS_PER_EMUSHORT, nb );

  } /* End for( i = 0; i < ns + 1; i++ ) */

  if( j ) j = (EMUSHORT)1;

  /* FREE pcpy_num **********/
  /* FREE pcpy_mul **********/
  /* FREE tprod *************/
  __mpu_sbrk( -(int)(3*np*SIZE_OF_EMUSHORT) );
  /**************************/

  return( (int)j );

} /* End of ei_mulm() */



/***************************************************************
  ROUNDOFF parameter register control.
  =  ==    =         =        =
  регистр управления параметрами ОКРУГЛЕНИЯ.
 ***************************************************************/
int rndprc = NSBITS_DEFAULT;

static int nsbits = NSBITS_DEFAULT; /* текущее    NSBITS(nb) */
static int            nslast  = -1; /* предыдущее NSBITS(nb) */

static int            rlast   = -1;
static int            rw      =  0; /* rounding word */
static EMUSHORT       rm_mask =  0;
static EMUSHORT       rm_bit  =  0;
static EMUSHORT       re_bit  =  0;
static int            re      =  0;


void ei_mdenorm( EMUSHORT *si, int lost, int subflag, EMUSHORT *exp, int rcontrol, int nb )
/***************************************************************

 Description        : ei_mdenorm() .

 Concepts           : .

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *si;       - указатель на
                                            internal e-type
                                            data struct - 
                                            число, подлежащее
                                            округлению;
                      int       lost;     - флаг бита,
                                            потерянного
                                            предыдущей
                                            операцией;
                      int       subflag;  - указывает на то,
                                            SI получено в
                                            результате
                                            операции
                                            вычитания. В том
                                            случае, когда
                                            LOST != 0, SI
                                            на самом деле
                                            немного меньше,
                                            чем дано;
                      EMUSHORT *exp;      - смещенный порядок,
                                            который может быть
                                            отрицательным.
                                            Поле Exponent
                                            параметра SI
                                            игнорируется, и
                                            замещается EXP,
                                            откорректированным
                                            в процессе
                                            нормализации и
                                            округления;
                      ВНИМАНИЕ: функция ei_mdenorm() СЧИТАЕТ, ЧТО
                                РАЗМЕР EXP РАВЕН
                                   internal_ne( nb ) + 1,
                                   =====================
                                   А ЗАТЕМ ПОРТИТ СОДЕРЖИМОЕ EXP.
                                   ==============================
                      int       rcontrol; - поле управления
                                            округлением. Если
                                            RCONTROL != 0, то
                                            SI будет округлено
                                            к RNDPRC битам;
                      int nb;             - количество бит в
                                            external e-type
                                            data struct.

 Return             : [void];

 ***************************************************************/
{
  EMUSHORT      *rbit = NULL,
                 *inc = NULL,
                *hexp = NULL; /* or 0 */
  EMUSHORT      *p;
  EMUSHORT       r;
  __mpu_int32_t  j;
  int            k;
  int            np, ne, ns, i;

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for rbit, inc, hexp . ******************/
  rbit = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !rbit )
  {
    /* fatal error */
    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE rbit **************/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  hexp = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !hexp )
  {
    /* fatal error */

    /* FREE rbit **************/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE inc ***************/
    __mpu_sbrk( -(int)((ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
   /************************************************************/

  if( nb < NBR_128 ) nb = NBR_128; /* т.к. NSBITS(32) = 16,
                                           NSBITS(64) = 48,
                                      остальные работают верно. */

  nsbits = NSBITS(nb); /* Actual number of bits in the Significand */

  for( i = 0; i < np;   i++ ) rbit[i] = (EMUSHORT)0;
  for( i = 0; i < ne+1; i++ ) hexp[i] = (EMUSHORT)0;
  for( i = 0; i < ne+1; i++ )  inc[i] = (EMUSHORT)0;


#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* low part */
  /* исходный формат HIGHT_EXP */
  p = hexp + ne;
  for( i = 0; i < ne - 1; i++ ) *p-- = MASK_ALL_BITS;
  *p = HIGHT_EXP;
#else
  /* low part */
  /* исходный формат HIGHT_EXP */
  p = hexp;
  for( i = 0; i < ne - 1; i++ ) *p++ = PART_MASK_ALL_BITS;
  *p = HIGHT_EXP;
#endif

  /* NORMALIZE */
  j = ei_normalize( si, nb );

  /* exp -= j */
  ei_cvte_unpack( inc, (EMUSHORT *)&j, ne+1, 1 );
  ei_sube( exp, exp, inc, ne+1 );

  /* exp < hexp */
  if( (j > (__mpu_int32_t)nsbits) &&
      ( ei_cmpe( exp, hexp, ne+1 ) < 0 )  ) /* exp < hexp */
  {
    /* FREE rbit **************/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE inc ***************/
    /* FREE hexp **************/
    __mpu_sbrk( -(int)(2*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    ei_cleazs( si, nb );
    return;
  }

  for( i = 0; i < ne+1; i++ ) inc[i] = (EMUSHORT)0;
  if( ei_cmpe( exp, inc, ne+1 ) < 0 ) /* exp < 0L */
  {
    j = -((__mpu_int32_t)nsbits)-1;
    ei_cvte_unpack( inc, (EMUSHORT *)&j, ne+1, 1 );
    if( ei_cmpe( exp, inc, ne+1 ) > 0 ) /* exp > (-NSBITS-1) */
    {
      ei_cvte_pack( (EMUSHORT *)&j, exp, 1, ne+1 );
      k = ei_shift( si, (int)j, nb );
      if( k ) lost = 1;
    }
    else
    {
      /* FREE rbit **************/
      __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
      /**************************/

      /* FREE inc ***************/
      /* FREE hexp **************/
      __mpu_sbrk( -(int)(2*(ne+1)*SIZE_OF_EMUSHORT) );
      /**************************/

      ei_cleazs( si, nb );
      return;

    } /* End if( exp > (-NSBITS-1) ) */

  } /* End if( exp < 0L ) */


  /* Round off, unless told not to by rcontrol */
  if( rcontrol == 0 ) goto md_final;

  /* Установить параметры если управляющий регистр изменен ||
     идет обработка другого типа вещественного числа */
  if( (rndprc != rlast) || (nsbits != nslast) )
  {
    switch( rndprc )
    {
      /*
        NOTE:
        HOST_BITS_PER_EMUSHORT == 16, 32, 64, 128,..., etc.
        ONLY.
       */
      default:
      case NSBITS_DEFAULT:
         /* Sign + Significand = NSBITS(nb)+1 */
#if HOST_BITS_PER_EMUSHORT > 32
        k = ns*BITS_PER_EMUSHORT - rndprc;
        if( (k > BITS_PER_EMUSHORT) || (k < 0) )
        {
          /* FREE rbit **************/
          __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
          /**************************/

          /* FREE inc ***************/
          /* FREE hexp **************/
          __mpu_sbrk( -(int)(2*(ne+1)*SIZE_OF_EMUSHORT) );
          /**************************/

          ei_cleazs( si, nb );
          return;
        }
        if( k )
        {
          int n;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
          re = rw = ne + ns + 1;
#else
          re = rw = 1;
#endif
          rm_mask = 0xffff;
          rm_bit  = 0x8000;
          re_bit  = (EMUSHORT)1;

          n = k - 16;
          while( n > 0 )
          {
            rm_mask <<= 16;
            rm_mask |= 0xffff;
            n -= 16;
          } /* End of while( n ) */
          rm_bit <<= k - 16;
          re_bit <<= k;
        }
        else
        {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
          rw = ne + ns + 2; /* lgw */
          re = rw - 1;
#else
          rw = 0; /* lgw */
          re = 1;
#endif
          rm_mask = MASK_ALL_BITS;
          rm_bit  = MASK_SIGN;
          re_bit  = (EMUSHORT)1;

        } /* End if( k ) */
#else  /* HOST_BITS_PER_EMUSHORT <= 32 */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
        rw = ne + ns + 2; /* lgw */
        re = rw - 1;
#else
        rw = 0; /* lgw */
        re = 1;
#endif
        rm_mask = MASK_ALL_BITS;
        rm_bit  = MASK_SIGN;
        re_bit  = (EMUSHORT)1;
#endif /* HOST_BITS_PER_EMUSHORT >  32 */
        break;

      case 53:
        /* NBR_64: Sign + Significand = 53 bits */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
        if( BITS_PER_EMUSHORT == 16 ) rw = ne + 5;
        else if( BITS_PER_EMUSHORT == 32 ) rw = ne + 3;
             else /* >= 64 */              rw = ne + 2;
#else
        if( BITS_PER_EMUSHORT == 16 ) rw = ns - 3;
        else if( BITS_PER_EMUSHORT == 32 ) rw = ns - 1;
             else /* >= 64 */              rw = ns;
#endif
        rm_mask = 0x07ff;
        rm_bit  = 0x0400;
        re_bit  = 0x0800;

#if HOST_BITS_PER_EMUSHORT > 64
        /* if( HOST_BITS_PER_EMUSHORT > 64 ) */
        { /* case HOST_BITS_PER_EMUSHORT == 128, 256,..., etc. */
          int n;

          n = (BITS_PER_EMUSHORT - 64);
          while( n > 0 )
          {
            rm_mask <<= 16;
            rm_mask |= 0xffff;
            n -= 16;
          } /* End of while( n ) */
          rm_bit  <<= (BITS_PER_EMUSHORT - 64);
          re_bit  <<= (BITS_PER_EMUSHORT - 64);
        }
#endif /* HOST_BITS_PER_EMUSHORT > 64 */
        re = rw;
        break;

      case 24:
        /* NBR_32: Sign + Significand = 24 bits */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
        if( BITS_PER_EMUSHORT == 16 ) rw = ne + 3;
        else /* >= 32 */              rw = ne + 2;
#else
        if( BITS_PER_EMUSHORT == 16 ) rw = ns - 1;
        else /* >= 32 */              rw = ns;
#endif
        rm_mask = 0x00ff;
        rm_bit  = 0x0080;
        re_bit  = 0x0100;
        if( BITS_PER_EMUSHORT > 32 )
        { /* case HOST_BITS_PER_EMUSHORT == 64, 128,..., etc. */
          int n;

          n = (BITS_PER_EMUSHORT - 32);
          while( n > 0 )
          {
            rm_mask <<= 16;
            rm_mask |= 0xffff;
            n -= 16;
          } /* End of while( n ) */
          rm_bit  <<= (BITS_PER_EMUSHORT - 32);
          re_bit  <<= (BITS_PER_EMUSHORT - 32);
        }
        re = rw;
        break;

    } /* End of switch( rndprc ) */

    /* rbit[re] = re_bit; */
    rlast    = rndprc;
    nslast   = nsbits;

  } /* End if( rndprc != rlast ) */
  /*
    Убрав следующий оператор из предыдущего блока
    мы обеспечили Static хранение массива rbit[]
    (наряду с rw, re, rm_mask, rm_bit, re_bit),
    содержащего 1 прибавляемый к мантиссе бит.
    SEE the following: ei_addm( si, si, rbit, nb );
   */
  rbit[re] = re_bit;


  /* Временный сдвиг вправо */
  for( i = 0; i < ne+1; i++ ) inc[i] = (EMUSHORT)0;
  if( ( ei_cmpe( exp, inc, ne+1 ) <= 0 ) && /* exp <= 0L */
      ( rndprc != (int)nsbits/*NSBITS(nb)*/ )        )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    lost |= si[ne+ns+2] & (EMUSHORT)1; /* lgw */
#else
    lost |= si[0]       & (EMUSHORT)1; /* lgw */
#endif
    ei_shdown( si, (unsigned)1, nb );
  }


  /* Очистить все биты ниже бита округления,
     запомнить в r, если какой-нибудь из них != 0 */
  r = si[rw] & rm_mask;
  if( rndprc < (int)nsbits )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    k = rw + 1;
    while( k < (int)np )
    {
      if( si[k] ) r |= (EMUSHORT)1;
      si[k] = (EMUSHORT)0;
      ++k;
    }
#else
    k = rw - 1;
    while( k >= 0 )
    {
      if( si[k] ) r |= (EMUSHORT)1;
      si[k] = (EMUSHORT)0;
      --k;
    }
#endif
  } /* End if( rndprc < NSBITS(nb) ) */
  si[rw] &= ~rm_mask;
  if( (r & rm_bit) != 0 ) /* Старший из отрезанных */
  {
    if( r == rm_bit ) /* Все отрезанные (кроме старшего) == 0 */
    {
      if( lost == 0 ) /* Потерянных ранее нет */
      {
        if( (si[re] & re_bit) == 0 ) /* Округление к четному */
          goto md_done;
      }
      else
      {
        if( subflag != 0 ) goto md_done;
      }

    } /* End if( r == rm_bit ) */

    ei_addm( si, si, rbit, nb );

  } /* End if( (r & rm_bit) != 0 ) */


md_done:
  /* UNDO: Временный сдвиг вправо */
  for( i = 0; i < ne+1; i++ ) inc[i] = (EMUSHORT)0;
  if( ( ei_cmpe( exp, inc, ne+1 ) <= 0 ) && /* exp <= 0L */
      ( rndprc != (int)nsbits/*NSBITS(nb)*/ )        )

  {
    ei_shup( si, (unsigned)1, nb );
  }


#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  if( si[ne+1] != (EMUSHORT)0 ) /* hgw */
#else
  if( si[ns+1] != (EMUSHORT)0 ) /* hgw */
#endif
  {
    /* overflow on roundoff */
    ei_shdown( si, (unsigned)1, nb );
    j = (__mpu_int32_t)1;
    /* exp += 1 */
    ei_cvte_unpack( inc, (EMUSHORT *)&j, ne+1, 1 );
    ei_adde( exp, exp, inc, ne+1 );
  }


md_final:
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  si[ne+ns+2] = (EMUSHORT)0; /* lgw */
#else
  si[0]       = (EMUSHORT)0; /* lgw */
#endif
  if( ei_cmpe( exp, hexp, ne+1 ) >= 0 ) /* exp >= hexp */
  {
    /* Формирование +/- 1.#INF */
    ei_cleazs( si, nb ); /* не трогать знак */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    ei_infin( si, si[0] != (EMUSHORT)0, nb );
#else
    ei_infin( si, si[ns + ne + 2] != (EMUSHORT)0, nb );
#endif
    /*
      MY ADD:
      "ovrflow range error"
     ***********************/
    /***************************************************
      NOTE:
         Функция _mtherr() является переходником между
         внутренним форматом и внешней,
         переопределяемой пользователем, функцией
         __mpu_math_error(). Кроме основных действий
         она выставляет системную переменную errno
         следующим образом.

           errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( (EMUSHORT *)0, /* Not change */
             (__mpu_char8_t *)"ei_mdenorm", __OVERFLOW__,
             (EMUSHORT *)0,
             (EMUSHORT *)0, (EMUSHORT *)0, nb );
    __STOVF; /* Set REAL Overflow Flag */

    /* FREE rbit **************/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE inc ***************/
    /* FREE hexp **************/
    __mpu_sbrk( -(int)(2*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;

  } /* End if( exp >= HIGHT_EXP ) */

  for( i = 0; i < ne+1; i++ ) inc[i] = (EMUSHORT)0;
  if( ei_cmpe( exp, inc, ne+1 ) < 0 ) /* exp < 0L */
  {
    /* si[exp] = 0   */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    p = inc + 1;
    ei_cpye_unpack( &si[1],    p, ne, ne );
#else
    p = inc;
    ei_cpye_unpack( &si[ns+2], p, ne, ne );
#endif
  }
  else /* exp >= 0L */
  {
    /* si[exp] = exp */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    p = exp + 1;
    ei_cpye_unpack( &si[1],    p, ne, ne );
#else
    p = exp;
    ei_cpye_unpack( &si[ns+2], p, ne, ne );
#endif
  } /* End if( exp < 0L ) */

  /* FREE rbit **************/
  __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
  /**************************/

  /* FREE inc ***************/
  /* FREE hexp **************/
  __mpu_sbrk( -(int)(2*(ne+1)*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_mdenorm() */


static void pack_32( EMUSHORT *ee, EMUSHORT *ei, int nb )
/***************************************************************

 Description        : pack_32() Пакует internal e-type data
                                struct в real32 data struct.

 Concepts           :

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void];

 ***************************************************************/
{
  EMUSHORT       *exone = NULL,
                   *exp = NULL,
                   *inc = NULL;
  EMUSHORT       *p;
  __mpu_uint16_t *he, *pe;
  int             rndsave;
  EMUSHORT        k;
  int             np, ne, ns, i;

  if( nb != NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  errno = 0;

  e_signull( ee, (unsigned)0, nb ); /* clear out exploded external
                                       real number. */

  if( ei_isind( ei, nb ) )
  {
    e_ind( ee, nb );
    return;
  }

  if( ei_isnanmin( ei, nb ) )
  {
    e_nanmin( ee, (unsigned)ei_isneg( ei, nb ), nb );
    return;
  }

  if( ei_isnanmax( ei, nb ) )
  {
    e_nanmax( ee, (unsigned)ei_isneg( ei, nb ), nb );
    return;
  }

  if( ei_isnans( ei, nb ) )
  {
    e_nan( ee, (unsigned)ei_isneg( ei, nb ), nb );
    return;
  }


  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for exone, exp, inc . ******************/
  exone = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !exone )
  {
    /* fatal error */
    return;
  }

  exp = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !exp )
  {
    /* fatal error */

    /* FREE exone *************/
    __mpu_sbrk( -(int)((ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE exp ***************/
    __mpu_sbrk( -(int)(2*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  for( i = 0; i < ne+1; i++ ) inc[i] = (EMUSHORT)0;
  for( i = 0; i < ne+1; i++ ) exp[i] = (EMUSHORT)0;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* low part */
  p = inc + ne;
  *p = (EMUSHORT)0x7f;

  /* hight part */
  p = exone;
  *p++ = (EMUSHORT)0;
  *p++ = HIGHT_EXONE; /* 0x3fff... */
  for( i = 0; i < ne - 1; i++ ) *p++ = MASK_ALL_BITS;
#else
  /* low part */
  p = inc;
  *p = (EMUSHORT)0x7f;

  /* hight part */
  p = exone + ne;
  *p-- = (EMUSHORT)0;
  *p-- = HIGHT_EXONE;
  for( i = 0; i < ne - 1; i++ ) *p-- = MASK_ALL_BITS;
#endif

  /* Copy Exponent */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( exp, &ei[1],    ne+1, ne );
#else
  ei_cpye_unpack( exp, &ei[ns+2], ne+1, ne );
#endif

  /* exp = exp - (EXONEsource - EXONEtarget) */
  ei_sube( exone, exone,   inc, ne+1 );
  ei_sube(   exp,   exp, exone, ne+1 );

  if( !ei_isinfin( ei, nb ) )
  {
     rndsave = rndprc;
     rndprc = 24;
     ei_mdenorm( ei, 0, 0, exp, NSBITS_DEFAULT, nb );
     rndprc = rndsave;
  }

  he = (__mpu_uint16_t *)ee;

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  ++he; /* point to high word16bits */
#endif

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p = ei;          /* point to Sign */
#else
  p = ei + np - 1; /* point to Sign */
#endif

  if( *p )
  {
    *he = 0x8000; /* output Sign bit */
  }

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p += ne;   /* point to low part of Exponent */
  k  = *p++; /* NOW: p point to hgw */
#else
  p -= ne;   /* point to low part of Exponent */
  k  = *p--; /* NOW: p point to hgw */
#endif

  /* Handle overflow cases. */
  if( k >= (EMUSHORT)255 ) /* hex: 0x00ff */
  {
    e_infin( ee, (unsigned)ei_isneg( ei, nb ), nb );
    errno = ERANGE; /* USER's Variable */
    __STOVF; /* Set REAL Overflow Flag */

    /* FREE exone *************/
    /* FREE exp ***************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(3*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;

  } /* End if( k >= 255 ) */

  if( k == (EMUSHORT)0 )
  {
    ei_shift( ei, 7, nb );
  }
  else
  {
    k <<= 7;
    ei_shift( ei, 8, nb );
  }
  /* Убрать бывшую явной 1.0 */
  k |= *p & (EMUSHORT)0x7f;
  /* NOW: p point to hight part of Significand  */
  /* High order output already has sign bit set */
  *he |= (__mpu_uint16_t)k;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ++p;
  /* point to hight part of Exponent */
  pe  = (__mpu_uint16_t *)p;
  ++he;
#else
  --p;
  /* point to hight part of Exponent */
  pe  = (__mpu_uint16_t *)p;
  pe += (BITS_PER_EMUSHORT - 16) / 16;
  --he;
#endif

  *he = *pe;

  /* FREE exone *************/
  /* FREE exp ***************/
  /* FREE inc ***************/
  __mpu_sbrk( -(int)(3*(ne+1)*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of pack_32() */

static void pack_64( EMUSHORT *ee, EMUSHORT *ei, int nb )
/***************************************************************

 Description        : pack_64() Пакует internal e-type data
                                struct в real64 data struct.

 Concepts           :

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void];

 ***************************************************************/
{
  EMUSHORT       *exone = NULL,
                   *exp = NULL,
                   *inc = NULL;
  EMUSHORT       *p;
  __mpu_uint16_t *he, *pe;
  int             rndsave;
  EMUSHORT        k;
  int             np, ne, ns, i;

  if( nb != NBR_64 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  errno = 0;

  e_signull( ee, (unsigned)0, nb ); /* clear out exploded external
                                       real number. */

  if( ei_isind( ei, nb ) )
  {
    e_ind( ee, nb );
    return;
  }

  if( ei_isnanmin( ei, nb ) )
  {
    e_nanmin( ee, (unsigned)ei_isneg( ei, nb ), nb );
    return;
  }

  if( ei_isnanmax( ei, nb ) )
  {
    e_nanmax( ee, (unsigned)ei_isneg( ei, nb ), nb );
    return;
  }

  if( ei_isnans( ei, nb ) )
  {
    e_nan( ee, (unsigned)ei_isneg( ei, nb ), nb );
    return;
  }


  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for exone, exp, inc . ******************/
  exone = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !exone )
  {
    /* fatal error */
    return;
  }

  exp = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !exp )
  {
    /* fatal error */

    /* FREE exone *************/
    __mpu_sbrk( -(int)((ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE exp ***************/
    __mpu_sbrk( -(int)(2*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  for( i = 0; i < ne+1; i++ ) inc[i] = (EMUSHORT)0;
  for( i = 0; i < ne+1; i++ ) exp[i] = (EMUSHORT)0;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* low part */
  p = inc + ne;
  *p = (EMUSHORT)0x3ff;

  /* hight part */
  p = exone;
  *p++ = (EMUSHORT)0;
  *p++ = HIGHT_EXONE; /* 0x3fff... */
  for( i = 0; i < ne - 1; i++ ) *p++ = MASK_ALL_BITS;
#else
  /* low part */
  p = inc;
  *p = (EMUSHORT)0x3ff;

  /* hight part */
  p = exone + ne;
  *p-- = (EMUSHORT)0;
  *p-- = HIGHT_EXONE;
  for( i = 0; i < ne - 1; i++ ) *p-- = MASK_ALL_BITS;
#endif

  /* Copy Exponent */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( exp, &ei[1],    ne+1, ne );
#else
  ei_cpye_unpack( exp, &ei[ns+2], ne+1, ne );
#endif

  /* exp = exp - (EXONEsource - EXONEtarget) */
  ei_sube( exone, exone,   inc, ne+1 );
  ei_sube(   exp,   exp, exone, ne+1 );

  if( !ei_isinfin( ei, nb ) )
  {
     rndsave = rndprc;
     rndprc = 53;
     ei_mdenorm( ei, 0, 0, exp, NSBITS_DEFAULT, nb );
     rndprc = rndsave;
  }

  he = (__mpu_uint16_t *)ee;

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  he += 3; /* point to high word16bits */
#endif

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p = ei;          /* point to Sign */
#else
  p = ei + np - 1; /* point to Sign */
#endif

  if( *p )
  {
    *he = 0x8000; /* output Sign bit */
  }

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p += ne;   /* point to low part of Exponent */
  k  = *p++; /* NOW: p point to hgw */
#else
  p -= ne;   /* point to low part of Exponent */
  k  = *p--; /* NOW: p point to hgw */
#endif

  /* Handle overflow cases. */
  if( k >= (EMUSHORT)2047 ) /* hex: 0x07ff */
  {
    e_infin( ee, (unsigned)ei_isneg( ei, nb ), nb );
    errno = ERANGE; /* USER's Variable */
    __STOVF; /* Set REAL Overflow Flag */

    /* FREE exone *************/
    /* FREE exp ***************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(3*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;

  } /* End if( k >= 2047 ) */

  if( k == (EMUSHORT)0 )
  {
    ei_shift( ei, 4, nb );
  }
  else
  {
    k <<= 4;
    ei_shift( ei, 5, nb );
  }
  /* Убрать бывшую явной 1.0 */
  k |= *p & (EMUSHORT)0x0f;
  /* NOW: p point to hight part of Significand  */
  /* High order output already has sign bit set */
  *he |= (__mpu_uint16_t)k;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ++p;
  /* point to hight part of Exponent */
  pe  = (__mpu_uint16_t *)p;
  ++he;
  *he = *pe;
  *(he + 1) = *(++pe);
  *(he + 2) = *(++pe);
#else
  --p;
  /* point to hight part of Exponent */
  pe  = (__mpu_uint16_t *)p;
  pe += (BITS_PER_EMUSHORT - 16) / 16;
  --he;
  *he = *pe;
  *(he - 1) = *(--pe);
  *(he - 2) = *(--pe);
#endif

   /* FREE exone *************/
   /* FREE exp ***************/
   /* FREE inc ***************/
   __mpu_sbrk( -(int)(3*(ne+1)*SIZE_OF_EMUSHORT) );
   /**************************/

} /* End of pack_64() */

static void pack_np( EMUSHORT *ee, EMUSHORT *ei, int nb )
/***************************************************************

 Description        : pack_np() Пакует internal e-type data
                                struct в real128, real256,
                                ..., etc. data struct.

 Concepts           :
 
 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void];

 ***************************************************************/
{
  EMUSHORT    *exone = NULL,
                *exp = NULL,
                *inc = NULL;
  EMUSHORT    *p;
  EMUPART     *he, *pe;
  int          rndsave;
  int          np, ne, ns, nex, nsx, i;

  if( nb < NBR_128 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  errno = 0;

  e_signull( ee, (unsigned)0, nb ); /* clear out exploded external
                                       real number. */

  if( ei_isind( ei, nb ) )
  {
    e_ind( ee, nb );
    return;
  }

  if( ei_isnanmin( ei, nb ) )
  {
    e_nanmin( ee, (unsigned)ei_isneg( ei, nb ), nb );
    return;
  }

  if( ei_isnanmax( ei, nb ) )
  {
    e_nanmax( ee, (unsigned)ei_isneg( ei, nb ), nb );
    return;
  }

  if( ei_isnans( ei, nb ) )
  {
    e_nan( ee, (unsigned)ei_isneg( ei, nb ), nb );
    return;
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for exone, exp, inc . ******************/
  exone = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !exone )
  {
    /* fatal error */
    return;
  }

  exp = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !exp )
  {
    /* fatal error */

    /* FREE exone *************/
    __mpu_sbrk( -(int)((ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE exp ***************/
    __mpu_sbrk( -(int)(2*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  nex = EMUPARTSIZE(NEBITS(nb));
  nsx = EMUPARTSIZE(NSBITS(nb));

  for( i = 0; i < ne+1; i++ ) inc[i] = (EMUSHORT)0;
  for( i = 0; i < ne+1; i++ ) exp[i] = (EMUSHORT)0;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* целевой формат EXONE */
  /* low part */
  pe = (EMUPART *)(inc + ne);
  pe += (BITS_PER_EMUSHORT - BITS_PER_EMUPART) /
     /* ------------------------------------- */
                    BITS_PER_EMUPART;
  for( i = 0; i < nex - 1; i++ ) *pe-- = PART_MASK_ALL_BITS;
  *pe = PART_HIGHT_EXONE;

  /* исходный формат EXONE */
  /* hight part */
  p = exone;
  *p++ = (EMUSHORT)0;
  *p++ = HIGHT_EXONE; /* 0x3fff... */
  for( i = 0; i < ne - 1; i++ ) *p++ = MASK_ALL_BITS;
#else
  /* целевой формат EXONE */
  /* low part */
  pe = (EMUPART *)inc;
  for( i = 0; i < nex - 1; i++ ) *pe++ = PART_MASK_ALL_BITS;
  *pe = PART_HIGHT_EXONE;

  /* исходный формат EXONE */
  /* hight part */
  p = exone + ne;
  *p-- = (EMUSHORT)0;
  *p-- = HIGHT_EXONE;
  for( i = 0; i < ne - 1; i++ ) *p-- = MASK_ALL_BITS;
#endif

   /* Copy Exponent */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( exp, &ei[1],    ne+1, ne );
#else
  ei_cpye_unpack( exp, &ei[ns+2], ne+1, ne );
#endif

  /* exp = exp - (EXONEsource - EXONEtarget) */
  ei_sube( exone, exone,   inc, ne+1 );
  ei_sube(   exp,   exp, exone, ne+1 );

  if( !ei_isinfin( ei, nb ) )
  {
    rndsave = rndprc;
    rndprc = (int)NSBITS(nb);
    ei_mdenorm( ei, 0, 0, exp, (int)NSBITS(nb), nb );
    rndprc = rndsave;
  }

  he = (EMUPART *)ee;

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  he += nex + nsx - 1; /* point to high EMUPART */
#endif

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p = ei;          /* point to Sign */
#else
  p = ei + np - 1; /* point to Sign */
#endif

  if( *p )
  {
    *he = PART_MASK_SIGN; /* output Sign bit */
  }

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p += ne; /* NOW: p point to low part of Exponent */
#else
  p -= ne; /* NOW: p point to low part of Exponent */
#endif

  /* Copy Exponent */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( exp, &ei[1],    ne+1, ne );
#else
  ei_cpye_unpack( exp, &ei[ns+2], ne+1, ne );
#endif

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* целевой формат HIGHT_EXP */
  /* low part */
  pe = (EMUPART *)(inc + ne);
  pe += (BITS_PER_EMUSHORT - BITS_PER_EMUPART) /
     /* ------------------------------------- */
                    BITS_PER_EMUPART;
  for( i = 0; i < nex - 1; i++ ) *pe-- = PART_MASK_ALL_BITS;
  *pe = PART_HIGHT_EXP;
#else
  /* целевой формат HIGHT_EXP */
  /* low part */
  pe = (EMUPART *)inc;
  for( i = 0; i < nex - 1; i++ ) *pe++ = PART_MASK_ALL_BITS;
  *pe = PART_HIGHT_EXP;
#endif


  /* Handle overflow cases. */
  if( ei_cmpe( exp, inc, ne+1 ) >= 0 ) /* exp >= HIGHT_EXP */
  {
    e_infin( ee, (unsigned)ei_isneg( ei, nb ), nb );
    errno = ERANGE; /* USER's Variable */
    __STOVF; /* Set REAL Overflow Flag */

    /* FREE exone *************/
    /* FREE exp ***************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(3*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;

  } /* End if( exp >= HIGHT_EXP ) */

  for( i = 0; i < ne+1; i++ ) inc[i] = (EMUSHORT)0;
  if( ei_cmpe( exp, inc, ne+1 ) != 0 ) /* exp != NULL */
  {
    /* Убрать бывшую явной 1.0 */
    ei_shift( ei, 1, nb );
  }

  /* Copy Exponent */
  /* High order output already has sign bit set, and
     p point to low part of Exponent */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* low part */
  he = (EMUPART *)&ee[nex - 1];
  pe = (EMUPART *)p;
  pe += (BITS_PER_EMUSHORT - BITS_PER_EMUPART) /
     /* -------------------------------------- */
                    BITS_PER_EMUPART;
  for( i = 0; i < nex - 1; i++ ) *he-- = *pe--;
  *he |= *pe;
#else
  /* low part */
  he = (EMUPART *)&ee[ns];
  pe = (EMUPART *)p;
  for( i = 0; i < nex - 1; i++ ) *he++ = *pe++;
  *he |= *pe;
#endif

   /* Copy Significand */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  pe = (EMUPART *)&ei[ne + 2];
  he = (EMUPART *)&ee[nex];
  for( i = 0; i < nsx; i++ ) *he++ = *pe++;
#else
  pe = (EMUPART *)&ei[ns];
  he = (EMUPART *)&ee[ns-1];
  pe += (BITS_PER_EMUSHORT - BITS_PER_EMUPART) /
     /* ------------------------------------- */
                    BITS_PER_EMUPART;
  he += (BITS_PER_EMUSHORT - BITS_PER_EMUPART) /
     /* ------------------------------------- */
                    BITS_PER_EMUPART;
  for( i = 0; i < nsx; i++ ) *he-- = *pe--;
#endif

  /* FREE exone *************/
  /* FREE exp ***************/
  /* FREE inc ***************/
  __mpu_sbrk( -(int)(3*(ne+1)*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of pack_np() */

void pack( EMUSHORT *ee, EMUSHORT *ei, int nb )
/***************************************************************

 Description        : pack() Пакует all e-type data struct
                             в `real<all>' data struct

 Concepts           :

 Use Global Variable:

 Use Functions      :
                      pack_32( *ee, *ei, nb );    | this file
                      pack_64( *ee, *ei, nb );    | this file
                      pack_np( *ee, *ei, nb );    | this file

 Parameters         : EMUSHORT *ee; - указатель на
                                      external e-type
                                      data struct;
                      EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : [void];

 ***************************************************************/
{
  EMUSHORT *eix = NULL; /* Internal format */
  int       np;

  if( nb < NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  np = internal_np( nb );

  /*** Allocate memory for eix . ******************************/
  eix = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !eix )
  {
    /* fatal error */
    return;
  }
  /************************************************************/

  /* copy EI to EIX (Internal format) */
  (void)memcpy( (void *)eix, (void *)ei, (size_t)(np*SIZE_OF_EMUSHORT) );

  switch( nb )
  {
    case NBR_32    :
      pack_32( ee, eix, nb );
      break;
    case NBR_64    :
      pack_64( ee, eix, nb );
      break;
    case NBR_128   :
    case NBR_256   :
    case NBR_512   :
    case NBR_1024  :
    case NBR_2048  :
    case NBR_4096  :
    case NBR_8192  :
    case NBR_16384 :
    case NBR_32768 :
    case NBR_65536 :
    case NBR_131072:
      pack_np( ee, eix, nb );
      break;

    default:
    {
      /* error: Invalid size of operand(s) */
      __real_error_no = __R_ESIZE__;
      __STIND; /* Set REAL ind-produsing operation Flag */
      break;
    }
  } /* End of switch( nb ) */

  /* FREE eix ***************/
  __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
  /**************************/

  return;

} /* End of pack() */


void ei_copy( EMUSHORT *eia, EMUSHORT *eib, int nb )
/***************************************************************

 Description        : ei_copy() Работает с
                                internal e-type data struct.

 Concepts           : copy (EIB to EIA) exploded
                      internal e-type real number.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *eia; - указатель на
                                       internal e-type
                                       data struct.
                                       TARGET;
                      EMUSHORT *eib; - указатель на
                                       internal e-type
                                       data struct.
                                       SOURCE;
                      int nb;        - количество бит в
                                       external e-type
                                       data struct.

 Return             : [void]

 ***************************************************************/
{
  int np;

  np = internal_np( nb );

  (void)memcpy( (void *)eia, (void *)eib, np * SIZE_OF_EMUSHORT );

} /* End of ei_copy() */

void ei_copyzlgw( EMUSHORT *eia, EMUSHORT *eib, int nb )
/***************************************************************

 Description        : ei_copyzlgw() Работает с
                                    internal e-type data
                                    struct.

 Concepts           : copy (EIB to EIA) exploded
                      internal e-type real number.
                      And clear low guard word.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *eia; - указатель на
                                       internal e-type
                                       data struct.
                                       TARGET;
                      EMUSHORT *eib; - указатель на
                                       internal e-type
                                       data struct.
                                       SOURCE;
                      int nb;        - количество бит в
                                       external e-type
                                       data struct.

 Return             : [void]

 ***************************************************************/
{
  int np;

  np = internal_np( nb );

  (void)memcpy( (void *)eia, (void *)eib, np * SIZE_OF_EMUSHORT );

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
   eia[np-1] = (EMUSHORT)0;
#else
   eia[0]    = (EMUSHORT)0;
#endif

} /* End of ei_copyzlgw() */

int ei_cmp( EMUSHORT *ai, EMUSHORT *bi, int nb )
/***************************************************************

 Description        : ei_cmp() Compare two numbers
                               in internal e-type data struct.

 Concepts           : Guard words are included in the
                      comparison.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         : EMUSHORT *ai; - указатель на
                                      internal e-type
                                      data struct;
                      EMUSHORT *bi; - указатель на
                                      internal e-type
                                      data struct;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.

 Return             : int rc; - Result of Comparison.

                        if( ai  > bi )        rc = +1;
                        if( ai == bi )        rc =  0;
                        if( ai  < bi )        rc = -1;
                        if((ai || bi) is NaN) rc = -2;

 ***************************************************************/
{
  EMUSHORT   *x, *y;
  EMUSHORT   *p, *q;
  int         msign;
  int         np, i;

  if( nb < NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return( -3 );
  }

  if( ei_isnanmin( ai, nb ) || ei_isnanmin( bi, nb ) ) return( -2 );
  if( ei_isnanmax( ai, nb ) || ei_isnanmax( bi, nb ) ) return( -2 );
  if( ei_isnans  ( ai, nb ) || ei_isnans  ( bi, nb ) ) return( -2 );
  if( ei_isind   ( ai, nb ) || ei_isind   ( bi, nb ) ) return( -2 );

  np = internal_np( nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  x = ai;     /* Point to Sign */
  y = bi;
  p = ai + 1; /* Point to hight part of Exponent */
  q = bi + 1;
#else
  x = ai + np - 1; /* Point to Sign */
  y = bi + np - 1;
  p = ai + np - 2; /* Point to hight part of Exponent */
  q = bi + np - 2;
#endif


  /* the Sign are different */
  if( *x != *y )
  {
    /* -0.0 equals +0.0 */
    for( i = 1; i < np; i++ ) /* lgw are included */
    {
      if( *p != (EMUSHORT)0 )
      {
        /* No Zero */
        if( *x == (EMUSHORT)0 ) return(  1 );
        else                    return( -1 );
      }
      if( *q != (EMUSHORT)0 )
      {
        /* No Zero */
        if( *x == (EMUSHORT)0 ) return(  1 );
        else                    return( -1 );
      }

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      ++p; ++q;
#else
      --p; --q;
#endif
    } /* End for( i = 1; i < np - 1; i++ ) */

    return( 0 );

  } /* End if( *x != *y ) */


  /* both are the same sign */
  if( *x == (EMUSHORT)0 ) msign =  1;
  else                    msign = -1;

  for( i = 0; i < np; i++ ) /* lgw are included */
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    if( *x++ != *y++ )
#else
    if( *x-- != *y-- )
#endif
    {
      /* different */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      if( *(--x) > *(--y) )
#else
      if( *(++x) > *(++y) )
#endif
        return(  msign );
      else
        return( -msign );

    } /* End if( *x++/-- != *y++/-- ) */

  } /* End for( i = 0; i < np; i++ ) */

  return( 0 ); /* equality */

} /* End of ei_cmp() */

static void ei_cvt_unpack( EMUSHORT *eia, EMUSHORT *eib, int nba, int nbb )
/***************************************************************

 Description        : ei_cvt_unpack() Работает с
                                      internal e-type data
                                      struct.

 Concepts           : convert (EIB to EIA) exploded
                      internal e-type real number.

 NOTE               : NBA > NBB.
                      Для real32, real64, and real128 EIA & EIB
                      могут указывать на одну и туже
                      internal e-type data struct, т.к.
                      внутренний формат этих чисел одинаков и
                      ei_cvt_unpack() работает с копией
                      EIB (p_b).

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *eia; - указатель на
                                       internal e-type
                                       data struct.
                                       TARGET;
                      EMUSHORT *eib; - указатель на
                                       internal e-type
                                       data struct.
                                       SOURCE;
                      int nba;       - количество бит в
                                       external e-type
                                       data struct.
                      int nbb;       - количество бит в
                                       external e-type
                                       data struct.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT      *exone = NULL,
                  *inc = NULL,
                    *r = NULL;
  EMUSHORT      *p;
  EMUSHORT      *he, *pe;
  EMUSHORT      *p_b = NULL; /* ptr to copy of EIB */
  int            denorm = 0;
  __mpu_int32_t  k;
  int            npa, nea, nsa, npb, neb, nsb, i;

  if( (nba < NBR_32) || (nbb < NBR_32) )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  npb = internal_np( nbb );
  neb = internal_ne( nbb );
  nsb = internal_ns( nbb );

  /*** Allocate memory for p_b . ******************************/
  p_b = (EMUSHORT *)__mpu_sbrk( (int)(npb*SIZE_OF_EMUSHORT) );
  if( !p_b )
  {
    /* fatal error */
    return;
  }
  /************************************************************/

  ei_copy( p_b, eib, nbb );

  he = p_b;
  ei_cleaz( eia, nba ); /* clear out exploded internal
                           e-type real number. (TARGET) */

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  he += neb;     /* point to low part of Exponent */
#else
  he += nsb + 2; /* point to low part of Exponent */
#endif

  npa = internal_np( nba );
  nea = internal_ne( nba );
  nsa = internal_ns( nba );

  /*** Allocate memory for exone, inc, r . ********************/
  exone = (EMUSHORT *)__mpu_sbrk( (int)(nea*SIZE_OF_EMUSHORT) );
  if( !exone )
  {
    /* fatal error */

    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)(nea*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE exone *************/
    __mpu_sbrk( -(int)(nea*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  r = (EMUSHORT *)__mpu_sbrk( (int)(nea*SIZE_OF_EMUSHORT) );
  if( !r )
  {
    /* fatal error */

    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE exone *************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(2*nea*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  /* inc используется для хранения EXONE исходного формата */
  /*
    но до ее основного применения она используется для:
    1) проверки всех бит исходной экспоненты на 1;
    2) проверки всех бит исходной экспоненты на 0;
   */
  for( i = 0; i < nea; i++ ) inc[i] = (EMUSHORT)0;
  for( i = 0; i < nea; i++ )   r[i] = (EMUSHORT)0;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* исходный формат EXP */
  /* low part */
  pe = inc + nea - 1;
  for( i = 0; i < neb - 1; i++ ) *pe-- = MASK_ALL_BITS;
  *pe = HIGHT_EXP;

  /* целевой формат EXONE */
  /* hight part */
  p = exone;
  *p++ = HIGHT_EXONE; /* 0x3fff... */
  for( i = 0; i < nea - 1; i++ ) *p++ = MASK_ALL_BITS;

  /* Copy Exponent */
  /* low part */
  pe = r + nea - 1;
  for( i = 0; i < neb; i++ ) *pe-- = *he--;
#else
  /* исходный формат EXP */
  /* low part */
  pe = inc;
  for( i = 0; i < neb - 1; i++ ) *pe++ = MASK_ALL_BITS;
  *pe = HIGHT_EXP;

  /* целевой формат EXONE */
  /* hight part */
  p = exone + nea - 1;
  *p-- = HIGHT_EXONE;
  for( i = 0; i < nea - 1; i++ ) *p-- = MASK_ALL_BITS;

  /* Copy Exponent */
  /* low part */
  pe = r;
  for( i = 0; i < neb; i++ ) *pe++ = *he++;
#endif

  /* NOW *he point to Sign in the source format */

  /* Sign */
  if( *he )
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  *eia = MASK_ALL_BITS;
#else
  *(eia + npa - 1) = MASK_ALL_BITS;
#endif


  /****************
    INFINITY
   ****************/

  if( ei_cmpe( r, inc, nea ) == 0 ) /* r == inc */
  {
    /********
      NANS
     ********/
    /* indeterminacy */
    if( ei_isind( p_b, nbb ) )
    {
      ei_ind( eia, nba );

      /* FREE p_b ***************/
      __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
      /**************************/

      /* FREE exone *************/
      /* FREE inc ***************/
      /* FREE r *****************/
      __mpu_sbrk( -(int)(3*nea*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }
    /* nanmin */
    if( ei_isnanmin( p_b, nbb ) )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      ei_nanmin( eia, eia[0] != (EMUSHORT)0, nba );
#else
      ei_nanmin( eia, eia[nsa + nea + 2] != (EMUSHORT)0, nba );
#endif

      /* FREE p_b ***************/
      __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
      /**************************/

      /* FREE exone *************/
      /* FREE inc ***************/
      /* FREE r *****************/
      __mpu_sbrk( -(int)(3*nea*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }
    /* nanmax */
    if( ei_isnanmax( p_b, nbb ) )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      ei_nanmax( eia, eia[0] != (EMUSHORT)0, nba );
#else
      ei_nanmax( eia, eia[nsa + nea + 2] != (EMUSHORT)0, nba );
#endif

      /* FREE p_b ***************/
      __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
      /**************************/

      /* FREE exone *************/
      /* FREE inc ***************/
      /* FREE r *****************/
      __mpu_sbrk( -(int)(3*nea*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }
    /* nans */
    if( ei_isnans( p_b, nbb ) )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      ei_nan( eia, eia[0] != (EMUSHORT)0, nba );
#else
      ei_nan( eia, eia[nsa + nea + 2] != (EMUSHORT)0, nba );
#endif

      /* FREE p_b ***************/
      __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
      /**************************/

      /* FREE exone *************/
      /* FREE inc ***************/
      /* FREE r *****************/
      __mpu_sbrk( -(int)(3*nea*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }
    /**********
      END NANS
     **********/

    ei_cleazs( eia, nba ); /* не трогать знак */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    ei_infin( eia, eia[0] != (EMUSHORT)0, nba );
#else
    ei_infin( eia, eia[nsa + nea + 2] != (EMUSHORT)0, nba );
#endif

    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE exone *************/
    /* FREE inc ***************/
    /* FREE r *****************/
    __mpu_sbrk( -(int)(3*nea*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /**************
    END INFINITY
   **************/


  /* If zero Exponent, then the Significand is denormalized.
     So take back the understood high Significand bit. */
  for( i = 0; i < nea; i++ ) inc[i] = (EMUSHORT)0;
  if( ei_cmpe( r, inc, nea ) == 0 ) /* r == inc (inc = 0) */
  {
    denorm = 1;
  }

  /* Create EXONE of source format */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* исходный формат EXONE */
  /* low part */
  pe = inc + neb - 1;
  for( i = 0; i < neb - 1; i++ ) *pe-- = MASK_ALL_BITS;
  *pe = HIGHT_EXONE;
#else
  /* исходный формат EXONE */
  /* low part */
  pe = inc;
  for( i = 0; i < neb - 1; i++ ) *pe++ = MASK_ALL_BITS;
  *pe = HIGHT_EXONE;
#endif

  /* r += EXONEtarget - EXONEsource */
  ei_sube( exone, exone,   inc, nea );
  ei_adde(     r,     r, exone, nea );
  /* Copy Exponent */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( &eia[1],     r, nea, nea );
#else
  ei_cpye_unpack( &eia[nsa+2], r, nea, nea );
#endif

  /* Copy Significand */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  pe = &eia[nea + 2];
  he = &p_b[neb + 2];
  for( i = 0; i < nsb; i++ ) *pe++ = *he++;
#else
  pe = &eia[nsa];
  he = &p_b[nsb];
  for( i = 0; i < nsb; i++ ) *pe-- = *he--;
#endif


  if( denorm )
  {
    /* if zero Exponent, then normalize the Significand */
    if( (k = ei_normalize(eia, nba)) > (__mpu_int32_t)EINSBITS(nba) )
      ei_cleazs( eia, nba );
    else
    {
      /* Exponent -= (k - 1); */
      k -= 1;
      ei_cvte_unpack( inc, (EMUSHORT *)&k, nea, 1 );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      p = &eia[1];
#else
      p = &eia[nsa+2];
#endif
      ei_sube( p, p, inc, nea );
    }
  } /* End if( denorm ) */

  /* FREE p_b ***************/
  __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
  /**************************/

  /* FREE exone *************/
  /* FREE inc ***************/
  /* FREE r *****************/
  __mpu_sbrk( -(int)(3*nea*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_cvt_unpack() */

static void ei_cvt_pack( EMUSHORT *eia, EMUSHORT *eib, int nba, int nbb )
/***************************************************************

 Description        : ei_cvt_pack() Работает с
                                    internal e-type data
                                    struct.

 Concepts           : convert (EIB to EIA) exploded
                      internal e-type real number.

 NOTE               : NBA < NBB.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         : EMUSHORT *eia; - указатель на
                                       internal e-type
                                       data struct.
                                       TARGET;
                      EMUSHORT *eib; - указатель на
                                       internal e-type
                                       data struct.
                                       SOURCE;
                      int nba;       - количество бит в
                                       external e-type
                                       data struct.
                      int nbb;       - количество бит в
                                       external e-type
                                       data struct.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT   *exone = NULL,
               *exp = NULL,
               *inc = NULL;
  EMUSHORT   *p;
  EMUSHORT   *he, *pe;
  EMUSHORT   *p_b = NULL; /* ptr to copy EIB */
  int         rndsave;
  int         npb, neb, nsb, nea, nsa, i;

  errno = 0;

  if( (nba < NBR_32) || (nbb < NBR_32) )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  npb = internal_np( nbb );
  neb = internal_ne( nbb );
  nsb = internal_ns( nbb );

  nea = internal_ne( nba );
  nsa = internal_ns( nba );

  /*** Allocate memory for p_b . ******************************/
  p_b = (EMUSHORT *)__mpu_sbrk( (int)(npb*SIZE_OF_EMUSHORT) );
  if( !p_b )
  {
    /* fatal error */
    return;
  }
  /************************************************************/

  ei_copy( p_b, eib, nbb );

  ei_signull( eia, (unsigned)0, nba ); /* clear out exploded internal
                                          e-type real number. */

  if( ei_isind( p_b, nbb ) )
  {
    ei_ind( eia, nba );

    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  if( ei_isnanmin( p_b, nbb ) )
  {
    ei_nanmin( eia, (unsigned)ei_isneg( p_b, nbb ), nba );

    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  if( ei_isnanmax( p_b, nbb ) )
  {
    ei_nanmax( eia, (unsigned)ei_isneg( p_b, nbb ), nba );

    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  if( ei_isnans( p_b, nbb ) )
  {
    ei_nan( eia, (unsigned)ei_isneg( p_b, nbb ), nba );

    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }


  /*** Allocate memory for exone, exp, inc . ******************/
  exone = (EMUSHORT *)__mpu_sbrk( (int)((neb+1)*SIZE_OF_EMUSHORT) );
  if( !exone )
  {
    /* fatal error */

    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  exp = (EMUSHORT *)__mpu_sbrk( (int)((neb+1)*SIZE_OF_EMUSHORT) );
  if( !exp )
  {
    /* fatal error */

    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE exone *************/
    __mpu_sbrk( -(int)((neb+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)((neb+1)*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE exone *************/
    /* FREE exp ***************/
    __mpu_sbrk( -(int)(2*(neb+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  for( i = 0; i < neb+1; i++ ) inc[i] = (EMUSHORT)0;
  for( i = 0; i < neb+1; i++ ) exp[i] = (EMUSHORT)0;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* целевой формат EXONE */
  /* low part */
  pe = inc + neb;
  for( i = 0; i < nea - 1; i++ ) *pe-- = MASK_ALL_BITS;
  *pe = HIGHT_EXONE;

  /* исходный формат EXONE */
  /* hight part */
  p = exone;
  *p++ = (EMUSHORT)0;
  *p++ = HIGHT_EXONE; /* 0x3fff... */
  for( i = 0; i < neb - 1; i++ ) *p++ = MASK_ALL_BITS;
#else
  /* целевой формат EXONE */
  /* low part */
  pe = inc;
  for( i = 0; i < nea - 1; i++ ) *pe++ = MASK_ALL_BITS;
  *pe = HIGHT_EXONE;

  /* исходный формат EXONE */
  /* hight part */
  p = exone + neb;
  *p-- = (EMUSHORT)0;
  *p-- = HIGHT_EXONE;
  for( i = 0; i < neb - 1; i++ ) *p-- = MASK_ALL_BITS;
#endif

  /* Copy Exponent */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( exp, &p_b[1],     neb+1, neb );
#else
  ei_cpye_unpack( exp, &p_b[nsb+2], neb+1, neb );
#endif

  /* exp = exp - (EXONEsource - EXONEtarget) */
  ei_sube( exone, exone,   inc, neb+1 );
  ei_sube(   exp,   exp, exone, neb+1 );

  if( !ei_isinfin( p_b, nbb ) )
  {
    rndsave = rndprc;
    rndprc = (int)EINSBITS(nbb);
    /*****************************************************************
      Здесь все равно какое значение RNDPRC, т.к. если оно не равно
      (24 или 53), то ei_mdenorm() округляет путем отбрасывания lgw
      данного ей числа в internal формате. Ловить здесь 24 или 53
      нет смысла (т.к. это будет сделано во время неминуемой
      последующей упаковки в external формат), а вот далее при
      копировании мантиссы можно заполнить lgw целевого формата
      для более точного округления при последующей упаковке.
      Мы использовали rndprc = (int)EINSBITS(nb); для того, чтобы
      избежать ошибок при больших размерах EMUSHORT.
     ******************************************************************/
    ei_mdenorm( p_b, 0, 0, exp, (int)EINSBITS(nbb), nbb );
    rndprc = rndsave;
  }

  he = eia;

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  he += nea + nsa + 2; /* point to Sign of TARGET */
#endif

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p = p_b;             /* point to Sign of SOURCE */
#else
  p = p_b + npb - 1;   /* point to Sign of SOURCE */
#endif

  if( *p )
  {
    *he = MASK_ALL_BITS; /* output Sign bit */
  }

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p += neb; /* NOW: p point to low part of Exponent */
#else
  p -= neb; /* NOW: p point to low part of Exponent */
#endif

  /* Copy Exponent */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( exp, &p_b[1],     neb+1, neb );
#else
  ei_cpye_unpack( exp, &p_b[nsb+2], neb+1, neb );
#endif

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* целевой формат HIGHT_EXP */
  /* low part */
  pe = inc + neb;
  for( i = 0; i < nea - 1; i++ ) *pe-- = MASK_ALL_BITS;
  *pe = HIGHT_EXP;
#else
  /* целевой формат HIGHT_EXP */
  /* low part */
  pe = inc;
  for( i = 0; i < nea - 1; i++ ) *pe++ = MASK_ALL_BITS;
  *pe = HIGHT_EXP;
#endif


  /* Handle overflow cases. */
  if( ei_cmpe( exp, inc, neb+1 ) >= 0 ) /* exp >= HIGHT_EXP */
  {
    ei_infin( eia, (unsigned)ei_isneg( p_b, nbb ), nba );
    errno = ERANGE; /* USER's Variable */
    __STOVF; /* Set REAL Overflow Flag */

    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE exone *************/
    /* FREE exp ***************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(3*(neb+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;

  } /* End if( exp >= HIGHT_EXP ) */


  /* Copy Exponent */
  /* High order output already has sign bit set, and
     p point to low part of Exponent of SOURCE */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* low part */
  he = &eia[nea];
  pe = p;
  for( i = 0; i < nea - 1; i++ ) *he-- = *pe--;
  *he = *pe;
#else
  /* low part */
  he = &eia[nsa + 2];
  pe = p;
  for( i = 0; i < nea - 1; i++ ) *he++ = *pe++;
  *he = *pe;
#endif

  /* Copy Significand */
  /***********************************************************
    Я ВКЛЮЧИЛ lgw ДЛЯ БОЛЕЕ ТОЧНОГО ОКРУГЛЕНИЯ ПРИ
    ПОСЛЕДУЮЩИХ ОПЕРАЦИЯХ С ПОЛУЧЕННЫМ ЧИСЛОМ.
    SEE:
      for( i = 0; i < nSa + 1; i++ ) *he++/-- = *pe++/--;
                     =======
   ***********************************************************/
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  pe = &p_b[neb + 2];
  he = &eia[nea + 2];
  for( i = 0; i < nsa/* + 1*/; i++ ) *he++ = *pe++;
#else
  pe = &p_b[nsb];
  he = &eia[nsa];
  for( i = 0; i < nsa/* + 1*/; i++ ) *he-- = *pe--;
#endif

  /* FREE p_b ***************/
  __mpu_sbrk( -(int)(npb*SIZE_OF_EMUSHORT) );
  /**************************/

  /* FREE exone *************/
  /* FREE exp ***************/
  /* FREE inc ***************/
  __mpu_sbrk( -(int)(3*(neb+1)*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_cvt_pack() */

void ei_convert( EMUSHORT *eia, EMUSHORT *eib, int nba, int nbb )
/***************************************************************

 Description        : ei_convert() Работает с
                                   internal e-type data struct.

 Concepts           : convert (EIB to EIA) exploded
                      internal e-type real number.

 Use Global Variable:

 Use Functions      :

 Parameters         : EMUSHORT *eia; - указатель на
                                       internal e-type
                                       data struct.
                                       TARGET;
                      EMUSHORT *eib; - указатель на
                                       internal e-type
                                       data struct.
                                       SOURCE;
                      int nba;       - количество бит в
                                       external e-type
                                       data struct.
                      int nbb;       - количество бит в
                                       external e-type
                                       data struct.

 Return             : [void]

 ***************************************************************/
{

  if( nba == nbb )
  {
    ei_copy( eia, eib, nba );
    return;
  }
  if( nba  > nbb )
  {
    ei_cvt_unpack( eia, eib, nba, nbb );
    return;
  }
  if( nba  < nbb )
  {
    ei_cvt_pack( eia, eib, nba, nbb );
    return;
  }

} /* End of ei_convert() */



static int subflag = 0;

static void ei_add1( EMUSHORT *eic, EMUSHORT *eia, EMUSHORT *eib, int nb )
/***************************************************************

 Description        : ei_add1() Работает с
                                internal e-type data struct.

 Concepts           : Arithmetic common to both addition and
                      substraction.
                      EIC = EIA + EIB or
                      EIC = EIA - EIB.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         :
                      EMUSHORT *eic; - указатель на
                                       internal e-type
                                       data struct.
                                       TARGET;
                      EMUSHORT *eia; - указатель на
                                       internal e-type
                                       data struct.
                                       ;
                      EMUSHORT *eib; - указатель на
                                       internal e-type
                                       data struct.
                                       ;
                      int nb;        - количество бит в
                                       external e-type
                                       data struct.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT      *lt  = NULL,
                *lta = NULL,
                *ltb = NULL,
                *inc = NULL;
  EMUSHORT      *p;
  __mpu_int32_t  j;
  int            rndsave;
  int            lost, k;
  int            np, ne, ns, i;

  if( ei_isinfin( eib, nb ) )
  {
    ei_copy( eic, eib, nb );
    if( subflag )
    {
      ei_neg( eic, nb );
    }
    return;
  }

  if( ei_isinfin( eia, nb ) )
  {
    ei_copy( eic, eia, nb );
    return;
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for lt, lta, ltb, inc . ****************/
  lt = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !lt )
  {
    /* fatal error */
    return;
  }

  lta = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !lta )
  {
    /* fatal error */

    /* FREE lt ****************/
    __mpu_sbrk( -(int)((ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  ltb = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !ltb )
  {
    /* fatal error */

    /* FREE lt ****************/
    /* FREE lta ***************/
    __mpu_sbrk( -(int)(2*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE lt ****************/
    /* FREE lta ***************/
    /* FREE ltb ***************/
    __mpu_sbrk( -(int)(3*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  if( nb < NBR_128 ) nb = NBR_128; /* т.к. NSBITS(32) = 16,
                                           NSBITS(64) = 48,
                                      остальные работают верно. */

  for( i = 0; i < ne+1; i++ ) inc[i] = (EMUSHORT)0;
  for( i = 0; i < ne+1; i++ ) lt [i] = (EMUSHORT)0;
  for( i = 0; i < ne+1; i++ ) lta[i] = (EMUSHORT)0;
  for( i = 0; i < ne+1; i++ ) ltb[i] = (EMUSHORT)0;

  if( subflag )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    eib[0] = ~eib[0]; 
#else
    eib[ne+ns+2] = ~eib[ne+ns+2];
#endif
  }

  /* Copy Exponents */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( lta, &eia[1],    ne+1, ne );
  ei_cpye_unpack( ltb, &eib[1],    ne+1, ne );
#else
  ei_cpye_unpack( lta, &eia[ns+2], ne+1, ne );
  ei_cpye_unpack( ltb, &eib[ns+2], ne+1, ne );
#endif

  /* Compate Exponents */
  ei_sube( lt, ltb, lta, ne+1 );
  if( ei_cmpe( lt, inc, ne+1 ) > 0 ) /* lt > 0L */
  {
    /* put the larger number in EIA */
    ei_copyzlgw( eic, eia, nb ); /* EIC <- EIA */
    ei_copyzlgw( eia, eib, nb ); /* EIA <- EIB */
    ei_copyzlgw( eib, eic, nb ); /* EIB <- EIC */
    /* Copy Exponent */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    ei_cpye_unpack( lta, &eia[1],    ne+1, ne );
#else
    ei_cpye_unpack( lta, &eia[ns+2], ne+1, ne );
#endif
    ei_nege( lt, lt, ne+1 ); /* lt = -lt; */
  }
  lost = 0;
  if( ei_cmpe( lt, inc, ne+1 ) != 0 ) /* lt != 0L */
  {
    j = -((__mpu_int32_t)NSBITS(nb))-1;
    ei_cvte_unpack( inc, (EMUSHORT *)&j, ne+1, 1 );
    if( ei_cmpe( lt, inc, ne+1 ) < 0 ) /* lt < (-NSBITS-1) */
    {
      /* answer same as larger addend */
      ei_copy( eic, eia, nb );

      /* FREE lt ****************/
      /* FREE lta ***************/
      /* FREE ltb ***************/
      /* FREE inc ***************/
      __mpu_sbrk( -(int)(4*(ne+1)*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }
    ei_cvte_pack( (EMUSHORT *)&j, lt, 1, ne+1 );
    /* shift the smaller number down */
    lost = ei_shift( eib, (int)j, nb );
  }
  else /* т.е. lt == 0L */
  {
    /* Exponents were the same, so must compare Significands */
    k = ei_cmpm( eib, eia, nb );
    if( k == 0 )
    {
      /* the numbers are identical in magnitude */
      /* if different signs, result is zero */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      if( eia[0] != eib[0] )
#else
      if( eia[np-1] != eib[np-1] )
#endif
      {
        ei_signull( eic, (unsigned)0, nb );

        /* FREE lt ****************/
        /* FREE lta ***************/
        /* FREE ltb ***************/
        /* FREE inc ***************/
        __mpu_sbrk( -(int)(4*(ne+1)*SIZE_OF_EMUSHORT) );
        /**************************/

        return;
      }

      /* if same sign, result is double */
      /* double denormalized tiny number */
      for( i = 0; i < ne+1; i++ ) inc[i] = (EMUSHORT)0;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      p = &eia[ne+2];
      if( (ei_cmpe( &eia[1], inc, ne ) == 0) &&
         ((*p & MASK_SIGN) == (EMUSHORT)0) )
#else
      p = &eia[ns];
      if( (ei_cmpe( &eia[ns+2], inc, ne ) == 0) &&
         ((*p & MASK_SIGN) == (EMUSHORT)0) )
#endif
      {
        ei_shup( eia, (unsigned)1, nb );

        ei_copy( eic, eia, nb );

        /* FREE lt ****************/
        /* FREE lta ***************/
        /* FREE ltb ***************/
        /* FREE inc ***************/
        __mpu_sbrk( -(int)(4*(ne+1)*SIZE_OF_EMUSHORT) );
        /**************************/

        return;
      }

      /* add 1 to Exponent unless both are zero! */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      p = &eia[1];
#else
      p = &eia[ne+ns+1];
#endif
      for( i = 1; i < np - 1; i++ )
      {
        if( *p != (EMUSHORT)0 )
        {
           /* This could overflow,
              but let ei_copy() take care of that. */
           ei_ince( lta, lta, ne+1 ); /* lta += 1; */
           break;
        }
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
        ++p;
#else
        --p;
#endif
      } /* End for( i = 1; i < np - 1; i++ ) */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      ei_cpye_pack( &eia[1],    lta, ne, ne+1 );
#else
      ei_cpye_pack( &eia[ns+2], lta, ne, ne+1 );
#endif
      ei_copy( eic, eia, nb );

      /* FREE lt ****************/
      /* FREE lta ***************/
      /* FREE ltb ***************/
      /* FREE inc ***************/
      __mpu_sbrk( -(int)(4*(ne+1)*SIZE_OF_EMUSHORT) );
      /**************************/

      return;

    } /* End if( k == 0 ) */
    if( k > 0 )
    {
      /* put the larger number in EIA */
      ei_copyzlgw( eic, eia, nb ); /* EIC <- EIA */
      ei_copyzlgw( eia, eib, nb ); /* EIA <- EIB */
      ei_copyzlgw( eib, eic, nb ); /* EIB <- EIC */

    } /* End if( k > 0 ) */

  } /* End if( lt != 0L ) */


#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  if( eia[0] == eib[0] )
#else
  if( eia[np-1] == eib[np-1] )
#endif
  {
    ei_addm( eia, eia, eib, nb );
    subflag = 0;
  }
  else
  {
    ei_subm( eia, eia, eib, nb );
    subflag = 1;
  }

  rndsave = rndprc;
  rndprc = (int)EINSBITS(nb);
  /*****************************************************************
    Здесь все равно какое значение RNDPRC, т.к. если оно не равно
    (24 или 53), то ei_mdenorm() округляет путем отбрасывания lgw
    данного ей числа в internal формате.
    Мы использовали rndprc = (int)EINSBITS(nb); для того, чтобы
    избежать ошибок при больших размерах EMUSHORT.
   ******************************************************************/
  ei_mdenorm( eia, lost, subflag, lta, (int)EINSBITS(nb), nb );
  rndprc = rndsave;

  ei_copy( eic, eia, nb );

  /* FREE lt ****************/
  /* FREE lta ***************/
  /* FREE ltb ***************/
  /* FREE inc ***************/
  __mpu_sbrk( -(int)(4*(ne+1)*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_add1() */

void ei_add( EMUSHORT *eic, EMUSHORT *eia, EMUSHORT *eib, int nb )
/***************************************************************

 Description        : ei_add() Работает с
                               internal e-type data struct.

 Concepts           : EIC = EIA + EIB.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         :
                      EMUSHORT *eic; - указатель на
                                       internal e-type
                                       data struct.
                                       TARGET;
                      EMUSHORT *eia; - указатель на
                                       internal e-type
                                       data struct.
                                       ;
                      EMUSHORT *eib; - указатель на
                                       internal e-type
                                       data struct.
                                       ;
                      int nb;        - количество бит в
                                       external e-type
                                       data struct.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT *p_a = NULL, *p_b = NULL;
  int       np;

  np = internal_np( nb );

  /*** Allocate memory for p_a, p_b . *************************/
  p_a = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !p_a )
  {
    /* fatal error */
    return;
  }

  p_b = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !p_b )
  {
    /* fatal error */

    /* FREE p_a ***************/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/


  ei_copy( p_a, eia, nb );
  ei_copy( p_b, eib, nb );

  /* EIA */
  /* InD plus anything is a InD */
  if( ei_isind( eia, nb ) )
  {
    /* "invalid operation" */
    ei_copy( eic, eia, nb );
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( eic, (__mpu_char8_t *)"add", __INVALID__, eic, p_a, p_b, nb );
    __STIND; /* Set REAL ind-produsing operation Flag */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /* NaN plus anything is a NaN */
  if( ei_isnans( eia, nb ) )
  {
    ei_copy( eic, eia, nb );

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  /* EIB */
  /* InD plus anything is a InD */
  if( ei_isind( eib, nb ) )
  {
    /* "invalid operation" */
    ei_copy( eic, eib, nb );
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( eic, (__mpu_char8_t *)"add", __INVALID__, eic, p_a, p_b, nb );
    __STIND; /* Set REAL ind-produsing operation Flag */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /* NaN plus anything is a NaN */
  if( ei_isnans( eib, nb ) )
  {
    ei_copy( eic, eib, nb );

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  /* Infinity minus infinity is a InD.
    Test for adding infinities of opposite signs. */
  if( ei_isinfin( eia, nb ) && ei_isinfin( eib, nb ) &&
      (ei_isneg( eia, nb ) ^ ei_isneg( eib, nb )) != 0  )
  {
    /* "invalid operation" */
    ei_ind( eic, nb );
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( eic, (__mpu_char8_t *)"sub", __INVALID__, eic, p_a, p_b, nb );
    __STIND; /* Set REAL ind-produsing operation Flag */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  subflag = 0;
  ei_add1( eic, p_a, p_b, nb );

  /* FREE p_a ***************/
  /* FREE p_b ***************/
  __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_add() */

void ei_sub( EMUSHORT *eic, EMUSHORT *eia, EMUSHORT *eib, int nb )
/***************************************************************

 Description        : ei_sub() Работает с
                               internal e-type data struct.

 Concepts           : EIC = EIA - EIB.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         :
                      EMUSHORT *eic; - указатель на
                                       internal e-type
                                       data struct.
                                       TARGET;
                      EMUSHORT *eia; - указатель на
                                       internal e-type
                                       data struct.
                                       ;
                      EMUSHORT *eib; - указатель на
                                       internal e-type
                                       data struct.
                                       ;
                      int nb;        - количество бит в
                                       external e-type
                                       data struct.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT *p_a = NULL, *p_b = NULL;
  int       np;

  np = internal_np( nb );

  /*** Allocate memory for p_a, p_b . *************************/
  p_a = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !p_a )
  {
    /* fatal error */
    return;
  }

  p_b = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !p_b )
  {
    /* fatal error */

    /* FREE p_a ***************/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  ei_copy( p_a, eia, nb );
  ei_copy( p_b, eib, nb );

  /* EIA */
  /* InD plus anything is a InD */
  if( ei_isind( eia, nb ) )
  {
    /* "invalid operation" */
    ei_copy( eic, eia, nb );
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( eic, (__mpu_char8_t *)"sub", __INVALID__, eic, p_a, p_b, nb );
    __STIND; /* Set REAL ind-produsing operation Flag */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /* NaN plus anything is a NaN */
  if( ei_isnans( eia, nb ) )
  {
    ei_copy( eic, eia, nb );

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  /* EIB */
  /* InD plus anything is a InD */
  if( ei_isind( eib, nb ) )
  {
    /* "invalid operation" */
    ei_copy( eic, eib, nb );
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( eic, (__mpu_char8_t *)"sub", __INVALID__, eic, p_a, p_b, nb );
    __STIND; /* Set REAL ind-produsing operation Flag */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /* NaN plus anything is a NaN */
  if( ei_isnans( eib, nb ) )
  {
    ei_copy( eic, eib, nb );

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  /* Infinity minus infinity is a InD.
    Test for adding infinities of opposite signs. */
  if( ei_isinfin( eia, nb ) && ei_isinfin( eib, nb ) &&
      (ei_isneg( eia, nb ) ^ ei_isneg( eib, nb )) == 0  )
  {
    /* "invalid operation" */
    ei_ind( eic, nb );
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( eic, (__mpu_char8_t *)"sub", __INVALID__, eic, p_a, p_b, nb );
    __STIND; /* Set REAL ind-produsing operation Flag */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }


  subflag = 1;
  ei_add1( eic, p_a, p_b, nb );

  /* FREE p_a ***************/
  /* FREE p_b ***************/
  __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_sub() */


void ei_div( EMUSHORT *eic, EMUSHORT *eia, EMUSHORT *eib, int nb )
/***************************************************************

 Description        : ei_div() Работает с
                               internal e-type data struct.

 Concepts           : EIC = EIA / EIB.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         :
                      EMUSHORT *eic; - указатель на
                                       internal e-type
                                       data struct.
                                       TARGET;
                      EMUSHORT *eia; - указатель на
                                       internal e-type
                                       data struct.
                                       ;
                      EMUSHORT *eib; - указатель на
                                       internal e-type
                                       data struct.
                                       ;
                      int nb;        - количество бит в
                                                external e-type
                                                data struct.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT        *p_a = NULL,
                  *p_b = NULL;
  EMUSHORT      *exone = NULL,
                  *lt  = NULL,
                  *lta = NULL,
                  *ltb = NULL;
  EMUSHORT      *p;
  __mpu_int32_t  j;
  int            k, rndsave;
  int            np, ne, ns, i;


  np = internal_np( nb );


  /*** Allocate memory for p_a, p_b . *************************/
  p_a = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !p_a )
  {
    /* fatal error */
    return;
  }

  p_b = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !p_b )
  {
    /* fatal error */

    /* FREE p_a ***************/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/


  ei_copy( p_a, eia, nb );
  ei_copy( p_b, eib, nb );

  /* EIA */
  /* InD plus anything is a InD */
  if( ei_isind( eia, nb ) )
  {
    /* "invalid operation" */
    ei_copy( eic, eia, nb );
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( eic, (__mpu_char8_t *)"div", __INVALID__, eic, p_a, p_b, nb );
    __STIND; /* Set REAL ind-produsing operation Flag */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /* NaN plus anything is a NaN */
  if( ei_isnans( eia, nb ) )
  {
    ei_copy( eic, eia, nb );

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  /* EIB */
  /* InD plus anything is a InD */
  if( ei_isind( eib, nb ) )
  {
    /* "invalid operation" */
    ei_copy( eic, eib, nb );
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( eic, (__mpu_char8_t *)"div", __INVALID__, eic, p_a, p_b, nb );
    __STIND; /* Set REAL ind-produsing operation Flag */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /* NaN plus anything is a NaN */
  if( ei_isnans( eib, nb ) )
  {
    ei_copy( eic, eib, nb );

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  /* Zero over zero, or infinity over infinity, is a InD. */
  if( ( ei_isinfin( eia, nb )   && ei_isinfin( eib, nb )   ) ||
      ( ei_issignull( eia, nb ) && ei_issignull( eib, nb ) )   )
  {
    /* "invalid operation" */
    ei_ind( eic, nb );
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( eic, (__mpu_char8_t *)"div", __INVALID__, eic, p_a, p_b, nb );
    __STIND; /* Set REAL ind-produsing operation Flag */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  /* Infinity over anything else is infinity. */
  if( ei_isinfin( eia, nb ) )
  {
    ei_infin( eic,
              (unsigned)(ei_isneg( eia, nb ) ^ ei_isneg( eib, nb )),
              nb );

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  /* Anything else over infinity is zero */
  if( ei_isinfin( eib, nb ) )
  {
    ei_signull( eic,
                (unsigned)(ei_isneg( eia, nb ) ^ ei_isneg( eib, nb )),
                nb );

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }


  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for lt, lta, ltb, exone . **************/
  lt = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !lt )
  {
    /* fatal error */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  lta = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !lta )
  {
    /* fatal error */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE lt ****************/
    __mpu_sbrk( -(int)((ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  ltb = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !ltb )
  {
    /* fatal error */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE lt ****************/
    /* FREE lta ***************/
    __mpu_sbrk( -(int)(2*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  exone = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !exone )
  {
    /* fatal error */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE lt ****************/
    /* FREE lta ***************/
    /* FREE ltb ***************/
    __mpu_sbrk( -(int)(3*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/


  /* Copy Exponents */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( lta, &p_a[1],    ne+1, ne );
  ei_cpye_unpack( ltb, &p_b[1],    ne+1, ne );
#else
  ei_cpye_unpack( lta, &p_a[ns+2], ne+1, ne );
  ei_cpye_unpack( ltb, &p_b[ns+2], ne+1, ne );
#endif


  for( i = 0; i < ne+1; i++ ) exone[i] = (EMUSHORT)0;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  if( ei_cmpe( &p_a[1],    exone, ne ) == 0 ) /* exp( a ) == 0 */
#else
  if( ei_cmpe( &p_a[ns+2], exone, ne ) == 0 ) /* exp( a ) == 0 */
#endif
  {
    /* See if numerator is zero. */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    p = &p_a[ne + 1]; /* hgw */
#else
    p = &p_a[ns + 1]; /* hgw */
#endif
    for( i = 0; i < ns+2; i++ )
    {
      if( *p != (EMUSHORT)0 )
      {
        /* lta -= ei_normalize( p_a, nb ); */
        j = ei_normalize( p_a, nb );
        ei_cvte_unpack( exone, (EMUSHORT *)&j, ne+1, 1 );
        ei_sube( lta, lta, exone, ne+1 );
        goto dnzro1;
      }
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      p++; /* to lgw */
#else
      p--; /* to lgw */
#endif
    } /* End for( i = 0; i < ns+2; i++ ) */
    ei_signull( eic,
                (unsigned)(ei_isneg( p_a, nb ) ^ ei_isneg( p_b, nb )),
                nb );

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE lt ****************/
    /* FREE lta ***************/
    /* FREE ltb ***************/
    /* FREE exone *************/
    __mpu_sbrk( -(int)(4*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;

  } /* End if( exp( a ) == 0 ) */

dnzro1:

  for( i = 0; i < ne+1; i++ ) exone[i] = (EMUSHORT)0;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  if( ei_cmpe( &p_b[1],    exone, ne ) == 0 ) /* exp( b ) == 0 */
#else
  if( ei_cmpe( &p_b[ns+2], exone, ne ) == 0 ) /* exp( b ) == 0 */
#endif
  {
    /* possible divide by zero. */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    p = &p_b[ne + 1]; /* hgw */
#else
    p = &p_b[ns + 1]; /* hgw */
#endif
    for( i = 0; i < ns+2; i++ )
    {
      if( *p != (EMUSHORT)0 )
      {
        /* ltb -= ei_normalize( p_b, nb ); */
        j = ei_normalize( p_b, nb );
        ei_cvte_unpack( exone, (EMUSHORT *)&j, ne+1, 1 );
        ei_sube( ltb, ltb, exone, ne+1 );
        goto dnzro2;
      }
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      p++; /* to lgw */
#else
      p--; /* to lgw */
#endif
    } /* End for( i = 0; i < ns+2; i++ ) */

    /* Divide by zero is not an invalid operation.
       It is a divide-by-zero operation! */
    ei_infin( eic,
              (unsigned)(ei_isneg( p_a, nb ) ^ ei_isneg( p_b, nb )),
              nb );
    /* Set SING for divide-by-zero operation! */
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( eic, (__mpu_char8_t *)"div", __SING__, eic, p_a, p_b, nb );
    __STSNG; /* Set REAL Singularity Flag */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE lt ****************/
    /* FREE lta ***************/
    /* FREE ltb ***************/
    /* FREE exone *************/
    __mpu_sbrk( -(int)(4*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;

  } /* End if( exp( b ) == 0 ) */

dnzro2:

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* формирование EXONE */
  /* hight part */
  p = exone;
  *p++ = (EMUSHORT)0;
  *p++ = HIGHT_EXONE; /* 0x3fff... */
  for( i = 0; i < ne - 1; i++ ) *p++ = MASK_ALL_BITS;
#else
  /* формирование EXONE */
  /* hight part */
  p = exone + ne;
  *p-- = (EMUSHORT)0;
  *p-- = HIGHT_EXONE;
  for( i = 0; i < ne - 1; i++ ) *p-- = MASK_ALL_BITS;
#endif


  k = ei_divm( p_a, p_a, p_b, nb );
  /* Calculate Exponent */
  /* lt = lta - ltb + EXONE; */
  ei_sube( lt, lta,  ltb, ne+1 );
  ei_adde( lt, lt, exone, ne+1 );

  rndsave = rndprc;
  rndprc = (int)EINSBITS(nb);
  /*****************************************************************
    Здесь все равно какое значение RNDPRC, т.к. если оно не равно
    (24 или 53), то ei_mdenorm() округляет путем отбрасывания lgw
    данного ей числа в internal формате.
    Мы использовали rndprc = (int)EINSBITS(nb); для того, чтобы
    избежать ошибок при больших размерах EMUSHORT.
   ******************************************************************/
  ei_mdenorm( p_a, k, 0, lt, (int)EINSBITS(nb), nb );
  rndprc = rndsave;

  ei_copy( eic, p_a, nb );

  /* Set the Sign */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p = eic;
#else
  p = eic + np - 1;
#endif

  if( ei_isneg( p_a, nb ) ^
      ei_isneg( p_b, nb )  ) *p = MASK_ALL_BITS;
  else                       *p = (EMUSHORT)0;

  /* FREE p_a ***************/
  /* FREE p_b ***************/
  __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
  /**************************/

  /* FREE lt ****************/
  /* FREE lta ***************/
  /* FREE ltb ***************/
  /* FREE exone *************/
  __mpu_sbrk( -(int)(4*(ne+1)*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_div() */

void ei_mul( EMUSHORT *eic, EMUSHORT *eia, EMUSHORT *eib, int nb )
/***************************************************************

 Description        : ei_mul() Работает с
                               internal e-type data struct.

 Concepts           : EIC = EIA * EIB.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         :
                      EMUSHORT *eic; - указатель на
                                       internal e-type
                                       data struct.
                                       TARGET;
                      EMUSHORT *eia; - указатель на
                                       internal e-type
                                       data struct.
                                       ;
                      EMUSHORT *eib; - указатель на
                                       internal e-type
                                       data struct.
                                       ;
                      int nb;        - количество бит в
                                       external e-type
                                       data struct.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT        *p_a = NULL,
                  *p_b = NULL;
  EMUSHORT      *exone = NULL,
                  *lt  = NULL,
                  *lta = NULL,
                  *ltb = NULL;
  EMUSHORT      *p;
  __mpu_int32_t  j;
  int            k, rndsave;
  int            np, ne, ns, i;


  np = internal_np( nb );


  /*** Allocate memory for p_a, p_b . *************************/
  p_a = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !p_a )
  {
    /* fatal error */
    return;
  }

  p_b = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !p_b )
  {
    /* fatal error */

    /* FREE p_a ***************/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/


  ei_copy( p_a, eia, nb );
  ei_copy( p_b, eib, nb );

  /* EIA */
  /* InD plus anything is a InD */
  if( ei_isind( eia, nb ) )
  {
    /* "invalid operation" */
    ei_copy( eic, eia, nb );
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( eic, (__mpu_char8_t *)"mul", __INVALID__, eic, p_a, p_b, nb );
    __STIND; /* Set REAL ind-produsing operation Flag */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /* NaN plus anything is a NaN */
  if( ei_isnans( eia, nb ) )
  {
    ei_copy( eic, eia, nb );

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  /* EIB */
  /* InD plus anything is a InD */
  if( ei_isind( eib, nb ) )
  {
    /* "invalid operation" */
    ei_copy( eic, eib, nb );
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( eic, (__mpu_char8_t *)"mul", __INVALID__, eic, p_a, p_b, nb );
    __STIND; /* Set REAL ind-produsing operation Flag */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /* NaN plus anything is a NaN */
  if( ei_isnans( eib, nb ) )
  {
    ei_copy( eic, eib, nb );

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }


  /* Zero over zero, or infinity over infinity, is a InD. */
  if( ( ei_isinfin( eia, nb ) && ei_issignull( eib, nb ) ) ||
      ( ei_isinfin( eib, nb ) && ei_issignull( eia, nb )     ) )
  {
    /* "invalid operation" */
    ei_ind( eic, nb );
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( eic, (__mpu_char8_t *)"mul", __INVALID__, eic, p_a, p_b, nb );
    __STIND; /* Set REAL ind-produsing operation Flag */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  /* Infinity over anything else is infinity. */
  if( ei_isinfin( eia, nb ) || ei_isinfin( eib, nb ) )
  {
    ei_infin( eic,
              (unsigned)(ei_isneg( eia, nb ) ^ ei_isneg( eib, nb )),
              nb );

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }


  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for lt, lta, ltb, exone . **************/
  lt = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !lt )
  {
    /* fatal error */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  lta = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !lta )
  {
    /* fatal error */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE lt ****************/
    __mpu_sbrk( -(int)((ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  ltb = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !ltb )
  {
    /* fatal error */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE lt ****************/
    /* FREE lta ***************/
    __mpu_sbrk( -(int)(2*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  exone = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !exone )
  {
    /* fatal error */

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE lt ****************/
    /* FREE lta ***************/
    /* FREE ltb ***************/
    __mpu_sbrk( -(int)(3*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/


  /* Copy Exponents */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( lta, &p_a[1],    ne+1, ne );
  ei_cpye_unpack( ltb, &p_b[1],    ne+1, ne );
#else
  ei_cpye_unpack( lta, &p_a[ns+2], ne+1, ne );
  ei_cpye_unpack( ltb, &p_b[ns+2], ne+1, ne );
#endif


  for( i = 0; i < ne+1; i++ ) exone[i] = (EMUSHORT)0;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  if( ei_cmpe( &p_a[1],    exone, ne ) == 0 ) /* exp( a ) == 0 */
#else
  if( ei_cmpe( &p_a[ns+2], exone, ne ) == 0 ) /* exp( a ) == 0 */
#endif
  {
    /* See if EIA is zero. */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    p = &p_a[ne + 1]; /* hgw */
#else
    p = &p_a[ns + 1]; /* hgw */
#endif
    for( i = 0; i < ns+2; i++ )
    {
      if( *p != (EMUSHORT)0 )
      {
        /* lta -= ei_normalize( p_a, nb ); */
        j = ei_normalize( p_a, nb );
        ei_cvte_unpack( exone, (EMUSHORT *)&j, ne+1, 1 );
        ei_sube( lta, lta, exone, ne+1 );
        goto mnzro1;
      }
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      p++; /* to lgw */
#else
      p--; /* to lgw */
#endif
    } /* End for( i = 0; i < ns+2; i++ ) */
    ei_signull( eic,
                (unsigned)(ei_isneg( p_a, nb ) ^ ei_isneg( p_b, nb )),
                nb );

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE lt ****************/
    /* FREE lta ***************/
    /* FREE ltb ***************/
    /* FREE exone *************/
    __mpu_sbrk( -(int)(4*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;

  } /* End if( exp( a ) == 0 ) */

mnzro1:

  for( i = 0; i < ne+1; i++ ) exone[i] = (EMUSHORT)0;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  if( ei_cmpe( &p_b[1],    exone, ne ) == 0 ) /* exp( b ) == 0 */
#else
  if( ei_cmpe( &p_b[ns+2], exone, ne ) == 0 ) /* exp( b ) == 0 */
#endif
  {
    /* possible divide by zero. */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    p = &p_b[ne + 1]; /* hgw */
#else
    p = &p_b[ns + 1]; /* hgw */
#endif
    for( i = 0; i < ns+2; i++ )
    {
      if( *p != (EMUSHORT)0 )
      {
        /* ltb -= ei_normalize( eib, nb ); */
        j = ei_normalize( p_b, nb );
        ei_cvte_unpack( exone, (EMUSHORT *)&j, ne+1, 1 );
        ei_sube( ltb, ltb, exone, ne+1 );
        goto mnzro2;
      }
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      p++; /* to lgw */
#else
      p--; /* to lgw */
#endif
    } /* End for( i = 0; i < ns+2; i++ ) */
    ei_signull( eic,
                (unsigned)(ei_isneg( p_a, nb ) ^ ei_isneg( p_b, nb )),
                nb );

    /* FREE p_a ***************/
    /* FREE p_b ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE lt ****************/
    /* FREE lta ***************/
    /* FREE ltb ***************/
    /* FREE exone *************/
    __mpu_sbrk( -(int)(4*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;

  } /* End if( exp( b ) == 0 ) */

mnzro2:

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* формирование EXONE */
  /* hight part */
  p = exone;
  *p++ = (EMUSHORT)0;
  *p++ = HIGHT_EXONE; /* 0x3fff... */
  for( i = 0; i < ne - 1; i++ ) *p++ = MASK_ALL_BITS;
#else
  /* формирование EXONE */
  /* hight part */
  p = exone + ne;
  *p-- = (EMUSHORT)0;
  *p-- = HIGHT_EXONE;
  for( i = 0; i < ne - 1; i++ ) *p-- = MASK_ALL_BITS;
#endif


  /* Multiply significands */
  k = ei_mulm( p_a, p_a, p_b, nb );
  /* Calculate Exponent */
  /* lt = lta + ltb - (EXONE - 1); */
  ei_adde( lt, lta,  ltb, ne+1 );
  ei_dece( exone,  exone, ne+1 );
  ei_sube( lt, lt, exone, ne+1 );

  rndsave = rndprc;
  rndprc = (int)EINSBITS(nb);
  /*****************************************************************
    Здесь все равно какое значение RNDPRC, т.к. если оно не равно
    (24 или 53), то ei_mdenorm() округляет путем отбрасывания lgw
    данного ей числа в internal формате.
    Мы использовали rndprc = (int)EINSBITS(nb); для того, чтобы
    избежать ошибок при больших размерах EMUSHORT.
   ******************************************************************/
  ei_mdenorm( p_a, k, 0, lt, (int)EINSBITS(nb), nb );
  rndprc = rndsave;

  ei_copy( eic, p_a, nb );

  /* Set the Sign of product */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p = eic;
#else
  p = eic + np - 1;
#endif

  if( ei_isneg( p_a, nb ) ^
      ei_isneg( p_b, nb )  ) *p = MASK_ALL_BITS;
  else                       *p = (EMUSHORT)0;

  /* FREE p_a ***************/
  /* FREE p_b ***************/
  __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
  /**************************/

  /* FREE lt ****************/
  /* FREE lta ***************/
  /* FREE ltb ***************/
  /* FREE exone *************/
  __mpu_sbrk( -(int)(4*(ne+1)*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_mul() */


void ei_ltor( EMUSHORT *ei, EMUSHORT *lp, int nb, int nlp )
/***************************************************************

 Description        : ei_ltor() Работает с
                                internal e-type data struct.

 Concepts           : Convert Signed integer *LP to internal
                      e-type data struct *EI.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         :
                      EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct.
                                      TARGET;
                      EMUSHORT *lp; - указатель на
                                      знаковое целое
                                      число.
                                      SOURCE;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.
                      int nlp;      - количество слов
                                      типа EMUSHORT в
                                      целом числе по
                                      указателю *lp.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT      *exone = NULL,
                  *inc = NULL,
                  *p_l = NULL; /* save *lp */
  EMUSHORT      *e, *p;
  __mpu_int32_t  k;
  int            np, ne, ns, i, n;

  if( nb < NBR_32 || nlp == 0 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for p_l . ******************************/
  p_l = (EMUSHORT *)__mpu_sbrk( (int)(nlp*SIZE_OF_EMUSHORT) );
  if( !p_l )
  {
    /* fatal error */
    return;
  }
  /************************************************************/

  /*** Allocate memory for exone, inc . ***********************/
  exone = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !exone )
  {
    /* fatal error */

    /* FREE p_l ***************/
    __mpu_sbrk( -(int)(nlp*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE p_l ***************/
    __mpu_sbrk( -(int)(nlp*SIZE_OF_EMUSHORT) );
    /**************************/
    /* FREE exone *************/
    __mpu_sbrk( -(int)(ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/


  ei_cleaz( ei, nb );
  if( ei_cmp0e( lp, nlp ) < 0 ) /* *LP < 0 */
  {
    /* Negate *LP */
    ei_nege( p_l, lp, nlp );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    /* put correct Sign in the Internal e-type number */
    ei[0]    = MASK_ALL_BITS;
#else
    /* put correct Sign in the Internal e-type number */
    ei[np-1] = MASK_ALL_BITS;
#endif
  }
  else
  {
    /* Copy *LP */
    for( i = 0; i < nlp; i++ ) p_l[i] = lp[i];

  } /* End if( *LP < 0 ) */


  /* Copy the LONG INTEGER to EI Significand area */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p = p_l;           /* hight part */
  e = &ei[ne+1];     /* hgw */
#else
  p = p_l + nlp - 1; /* hight part */
  e = &ei[ns+1];     /* hgw */
#endif

  /* if( nlp > ns ) low part of *LP my be LOST; */
  if( nlp >= ns ) n = ns;
  else            n = nlp;
  /* Copy the LONG INTEGER to EI Significand area */
  for( i = 0; i < n; i++ )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    *e++ = *p++;
#else
    *e-- = *p--;
#endif
  } /* End for( copy ) */

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* формирование EXONE */
  /* hight part */
  p = exone;
  *p++ = HIGHT_EXONE; /* 0x3fff... */
  for( i = 0; i < ne - 1; i++ ) *p++ = MASK_ALL_BITS;
#else
  /* формирование EXONE */
  /* hight part */
  p = exone + ne - 1;
  *p-- = HIGHT_EXONE;
  for( i = 0; i < ne - 1; i++ ) *p-- = MASK_ALL_BITS;
#endif

  /* Clear inc */
  for( i = 0; i < ne; i++ ) inc[i] = (EMUSHORT)0;
  /* Количество бит целого также (как и Significand)  ограничено
     знаковым числом, которое укладывается в тип signed EMUSHORT.
   */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  inc[ne-1] = (nlp-1)*BITS_PER_EMUSHORT - 1; /* low part */
#else
  inc[0]    = (nlp-1)*BITS_PER_EMUSHORT - 1;
#endif

  /*********************************
    For Correct SIGNED result!!!
   *********************************/
  ei_cvte_unpack( inc, inc, ne, 1 );

  /* put correct Exponent */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_adde( &ei[1],    exone, inc, ne );
#else
  ei_adde( &ei[ns+2], exone, inc, ne );
#endif

  /* normalize the Significand */
  if( (k = ei_normalize( ei, nb )) > (__mpu_int32_t)EINSBITS(nb) )
  {
    /* it was zero : это был нуль */
    ei_cleaz( ei, nb );
  }
  else
  {
    ei_cvte_unpack( inc, (EMUSHORT *)&k, ne, 1 );
    /* Exponent -= k; */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    ei_sube( &ei[1],    &ei[1],    inc, ne );
#else
    ei_sube( &ei[ns+2], &ei[ns+2], inc, ne );
#endif
  }

  /* FREE p_l ***************/
  __mpu_sbrk( -(int)(nlp*SIZE_OF_EMUSHORT) );
  /**************************/

  /* FREE exone *************/
  /* FREE inc ***************/
  __mpu_sbrk( -(int)(2*ne*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_ltor() */

void ei_ultor( EMUSHORT *ei, EMUSHORT *lp, int nb, int nlp )
/***************************************************************

 Description        : ei_ultor() Работает с
                                 internal e-type data struct.

 Concepts           : Convert UNsigned integer *LP to internal
                      e-type data struct *EI.

 Use Global Variable:

 Use Functions      : 
                    internal_ne( nb );           | this file
                    internal_ns( nb );           | this file

 Parameters         :
                      EMUSHORT *ei; - указатель на
                                      internal e-type
                                      data struct.
                                      TARGET;
                      EMUSHORT *lp; - указатель на
                                      беззнаковое целое
                                      число.
                                      SOURCE;
                      int nb;       - количество бит в
                                      external e-type
                                      data struct.
                      int nlp;      - количество слов
                                      типа EMUSHORT в
                                      целом числе по
                                      указателю *lp.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT      *exone = NULL,
                  *inc = NULL,
                  *p_l = NULL; /* save *lp */
  EMUSHORT      *e, *p;
  __mpu_int32_t  k;
  int            ne, ns, i, n;

  if( nb < NBR_32 || nlp == 0 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for p_l . ******************************/
  p_l = (EMUSHORT *)__mpu_sbrk( (int)(nlp*SIZE_OF_EMUSHORT) );
  if( !p_l )
  {
    /* fatal error */
    return;
  }
  /************************************************************/

  /*** Allocate memory for exone, inc . ***********************/
  exone = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !exone )
  {
    /* fatal error */

    /* FREE p_l ***************/
    __mpu_sbrk( -(int)(nlp*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE p_l ***************/
    __mpu_sbrk( -(int)(nlp*SIZE_OF_EMUSHORT) );
    /**************************/
    /* FREE exone *************/
    __mpu_sbrk( -(int)(ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/


  /* Copy *lp */
  for( i = 0; i < nlp; i++ ) p_l[i] = lp[i];

  ei_cleaz( ei, nb );

  /* Copy the LONG INTEGER to EI Significand area */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p = p_l;           /* hight part */
  e = &ei[ne+1];     /* hgw */
#else
  p = p_l + nlp - 1; /* hight part */
  e = &ei[ns+1];     /* hgw */
#endif

  /* if( nlp > ns ) low part of *LP my be LOST; */
  if( nlp >= ns ) n = ns;
  else            n = nlp;
  /* Copy the LONG INTEGER to EI Significand area */
  for( i = 0; i < n; i++ )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    *e++ = *p++;
#else
    *e-- = *p--;
#endif
  } /* End for( copy ) */

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* формирование EXONE */
  /* hight part */
  p = exone;
  *p++ = HIGHT_EXONE; /* 0x3fff... */
  for( i = 0; i < ne - 1; i++ ) *p++ = MASK_ALL_BITS;
#else
  /* формирование EXONE */
  /* hight part */
  p = exone + ne - 1;
  *p-- = HIGHT_EXONE;
  for( i = 0; i < ne - 1; i++ ) *p-- = MASK_ALL_BITS;
#endif

  /* Clear inc */
  for( i = 0; i < ne; i++ ) inc[i] = (EMUSHORT)0;
  /* Количество бит целого также (как и Significand)  ограничено
     знаковым числом, которое укладывается в тип signed EMUSHORT.
   */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  inc[ne-1] = (nlp-1)*BITS_PER_EMUSHORT - 1; /* low part */
#else
  inc[0]    = (nlp-1)*BITS_PER_EMUSHORT - 1;
#endif

  /*********************************
    For Correct SIGNED result!!!
   *********************************/
  ei_cvte_unpack( inc, inc, ne, 1 );

  /* put correct Exponent */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_adde( &ei[1],    exone, inc, ne );
#else
  ei_adde( &ei[ns+2], exone, inc, ne );
#endif

  /* normalize the Significand */
  if( (k = ei_normalize( ei, nb )) > (__mpu_int32_t)EINSBITS(nb) )
  {
    /* it was zero : это был нуль */
    ei_cleaz( ei, nb );
  }
  else
  {
    ei_cvte_unpack( inc, (EMUSHORT *)&k, ne, 1 );
    /* Exponent -= k; */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    ei_sube( &ei[1],    &ei[1],    inc, ne );
#else
    ei_sube( &ei[ns+2], &ei[ns+2], inc, ne );
#endif
  } /* End of normalize the Significand */

  /* FREE p_l ***************/
  __mpu_sbrk( -(int)(nlp*SIZE_OF_EMUSHORT) );
  /**************************/

  /* FREE exone *************/
  /* FREE inc ***************/
  __mpu_sbrk( -(int)(2*ne*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_ultor() */

void ei_rtoul_frac( EMUSHORT *lp, EMUSHORT *frac, EMUSHORT *ei, int nlp, int nb )
/***************************************************************

 Description        : ei_rtoul_frac() Работает с
                                      internal e-type data
                                      struct.

 Concepts           : Find Unsigned long INTEGER *LP and
                      floating point fractional part *FRAC of
                      Internal e-type floating point input *EI.
                      A negative input yields INTEGER output=0
                      but correct fraction.
                      The output Internal e-type fraction
                      *FRAC is the positive fractional part of
                      abs(*EI).

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         :
                      EMUSHORT *lp;   - указатель на
                                        беззнаковое целое
                                        число.
                                        TARGET;
                      EMUSHORT *frac; - указатель на
                                        internal e-type
                                        data struct.
                                        TARGET FRAC;
                      NOTE:
                         if( FRAC == 0 ) ei_rtoul_frac() просто
                                         не пытается вывести
                                         полученную дробную часть.

                      EMUSHORT *ei;   - указатель на
                                        internal e-type
                                        data struct.
                                        SOURCE;
                      int nlp;        - количество слов
                                        типа EMUSHORT в
                                        целом числе по
                                        указателю *lp.
                      int nb;         - количество бит в
                                        internal e-type
                                        data struct;
                                        SOURCE & *FRAC.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT      *exone = NULL,
                  *inc = NULL,
                    *k = NULL,
                   *fi = NULL; /* tmp for FRAC */
  EMUSHORT      *p;
  __mpu_int32_t  j;
  int            np, ne, ns, i;

  if( nb < NBR_32 || nlp == 0 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for exone, inc, k, fi . ****************/
  exone = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !exone )
  {
    /* fatal error */
    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE exone *************/
    __mpu_sbrk( -(int)(ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  k = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !k )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(2*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  fi = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !fi )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE inc ***************/
    /* FREE k *****************/
    __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/


  for( i = 0; i < nlp; i++ ) lp[i] = (EMUSHORT)0;

  ei_copy( fi, ei, nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* формирование EXONE */
  /* hight part */
  p = exone;
  *p++ = HIGHT_EXONE; /* 0x3fff... */
  for( i = 0; i < ne - 1; i++ ) *p++ = MASK_ALL_BITS;
#else
  /* формирование EXONE */
  /* hight part */
  p = exone + ne - 1;
  *p-- = HIGHT_EXONE;
  for( i = 0; i < ne - 1; i++ ) *p-- = MASK_ALL_BITS;
#endif

  /* k = Exponent( fi ) - (EXONE - 1); */
  ei_dece( exone, exone, ne ); /* save (EXONE - 1) */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_sube( k, &fi[1],    exone, ne );
#else
  ei_sube( k, &fi[ns+2], exone, ne );
#endif

  if( ei_cmp0e( k, ne ) <= 0 )
  {
    /* if( Exponent <= 0 ), integer = 0 and
                            real output is fraction */
    for( i = 0; i < nlp; i++ ) lp[i] = (EMUSHORT)0;
    if( frac ) ei_copy( frac, fi, nb );

    /* FREE exone *************/
    /* FREE inc ***************/
    /* FREE k *****************/
    __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE fi ****************/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  for( i = 0; i < ne; i++ ) inc[i] =  (EMUSHORT)0;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  inc[ne-1] = (EMUSHORT)(BITS_PER_EMUSHORT*nlp);
#else
  inc[0]    = (EMUSHORT)(BITS_PER_EMUSHORT*nlp);
#endif
  if( ei_cmpe( k, inc, ne ) > 0 ) /* k > inc */
  {
    /* long INTEGER overflow: output large integer and
                              correct fraction */
    /* In this case, return the largest unsigned INTEGER */
    for( i = 0; i < nlp; i++ ) lp[i] = MASK_ALL_BITS;

    /* Страховка на случай если
       k > max positive Signed EMUSHORT */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    inc[ne-1] = HIGHT_EXP;
#else
    inc[0]    = HIGHT_EXP;
#endif
    if( ei_cmpe( k, inc, ne ) > 0 )
    {
      ei_shift( fi, (ns+1)*BITS_PER_EMUSHORT, nb );
    }
    else
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      j = k[ne-1];
#else
      j = k[0];
#endif
      ei_shift( fi, j, nb );
    }

    if( __extra_warnings )
    {
      struct __exception  e;

      __real_error_no = __R_ETRUNC__;

      e.who          = _REAL_;
      e.type         = __real_error_no;
      e.name         = (__mpu_char8_t *)"ei_rtoul_frac";
      e.msg          = __mpu_utf8mpu_error( _REAL_, __real_error_no );
      e.msg_type     = _WARNING_MSG_;
      e.nb_a1        = 0;
      e.nb_a2        = 0;
      e.nb_rv        = 0;
      e.arg_1        = (unsigned char *)0;
      e.arg_2        = (unsigned char *)0;
      e.return_value = (unsigned char *)0;

      __mpu_warning( &e );

      if( e.msg ) free( e.msg );

    } /* End if( __extra_warnings ) */

  }
  else /* т.е. k <= (BITS_PER_EMUSHORT*nlp); */
  {
    /* NOTE: Здесь k > 0 */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    j = k[ne-1];
#else
    j = k[0];
#endif
    if( j > BITS_PER_EMUSHORT )
    {
      int n;

      n = j % BITS_PER_EMUSHORT;
      ei_shift( fi, n, nb );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      lp[nlp-1] = fi[ne+1]; /* hgw to low part */
#else
      lp[0]     = fi[ns+1];
#endif
      j -= n;
      do
      {
        ei_shup( fi, BITS_PER_EMUSHORT, nb );
        ei_shln( lp, lp, BITS_PER_EMUSHORT, nlp );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
        lp[nlp-1] = fi[ne+1]; /* hgw to low part */
#else
        lp[0]     = fi[ns+1];
#endif
      } while( (j -= BITS_PER_EMUSHORT) > 0 );

    }
    else
    {
      ei_shift( fi, j, nb );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      lp[nlp-1] = fi[ne+1]; /* hgw to low part */
#else
      lp[0]     = fi[ns+1];
#endif
    }

  } /* End if( k > BITS_PER_EMUSHORT*nlp ) */


#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  if( fi[0] )    /* if( Sign ) *LP = NULL; */
#else
  if( fi[np-1] ) /* if( Sign ) *LP = NULL; */
#endif
    for( i = 0; i < nlp; i++ ) lp[i] = (EMUSHORT)0;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  fi[0]    = (EMUSHORT)0;    /* Sign */
  ei_cpye( &fi[1], exone, ne, ne );
  fi[ne+1] = (EMUSHORT)0;    /*  hgw */
#else
  fi[np-1]    = (EMUSHORT)0; /* Sign */
  ei_cpye( &fi[ns+2], exone, ne, ne );
  fi[ns+1] = (EMUSHORT)0;    /*  hgw */
#endif

  /* normalize the Significand */
  if( (j = ei_normalize( fi, nb )) > (__mpu_int32_t)EINSBITS(nb) )
  {
    /* it was zero : это был нуль */
    ei_cleaz( fi, nb );
  }
  else
  {
    ei_cvte_unpack( inc, (EMUSHORT *)&j, ne, 1 );
    /* Exponent -= k; */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    ei_sube( &fi[1],    &fi[1],    inc, ne );
#else
    ei_sube( &fi[ns+2], &fi[ns+2], inc, ne );
#endif
  } /* End of normalize the Significand */

  if( frac ) ei_copy( frac, fi, nb );

  /* FREE exone *************/
  /* FREE inc ***************/
  /* FREE k *****************/
  __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
  /**************************/

  /* FREE fi ****************/
  __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_rtoul_frac() */

void ei_rtol_frac( EMUSHORT *lp, EMUSHORT *frac, EMUSHORT *ei, int nlp, int nb )
/***************************************************************

 Description        : ei_rtol_frac() Работает с
                                     internal e-type data
                                     struct.

 Concepts           : Find Signed long INTEGER *LP and floating
                      point fractional part *FRAC of Internal
                      e-type floating point input *EI.
                      The INTEGER output *LP has the sign of
                      the input *EI, except that positive
                      overflov is permitted
                      if FIXUNS_TRUNC_LIKE_FIX_TRUNC.
                      The output Internal e-type fraction
                      *FRAC is the positive fractional part of
                      abs(*EI).

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         :
                      EMUSHORT *lp;   - указатель на
                                        знаковое целое
                                        число.
                                        TARGET;
                      EMUSHORT *frac; - указатель на
                                        internal e-type
                                        data struct.
                                        TARGET FRAC;
                      NOTE:
                         if( FRAC == 0 ) ei_rtol_frac() просто
                                         не пытается вывести
                                         полученную дробную
                                         часть.

                      EMUSHORT *ei;   - указатель на
                                        internal e-type
                                        data struct.
                                        SOURCE;
                      int nlp;        - количество слов
                                        типа EMUSHORT в
                                        целом числе по
                                        указателю *lp.
                      int nb;         - количество бит в
                                        internal e-type
                                        data struct;
                                        SOURCE & *FRAC.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT      *exone = NULL,
                  *inc = NULL,
                    *k = NULL,
                   *fi = NULL; /* tmp for FRAC */
  EMUSHORT      *p;
  __mpu_int32_t  j;
  int            np, ne, ns, i;

  if( nb < NBR_32 || nlp == 0 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for exone, inc, k, fi . ****************/
  exone = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !exone )
  {
    /* fatal error */
    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE exone *************/
    __mpu_sbrk( -(int)(ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  k = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !k )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(2*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  fi = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !fi )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE inc ***************/
    /* FREE k *****************/
    __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/


  for( i = 0; i < nlp; i++ ) lp[i] = (EMUSHORT)0;

  ei_copy( fi, ei, nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* формирование EXONE */
  /* hight part */
  p = exone;
  *p++ = HIGHT_EXONE; /* 0x3fff... */
  for( i = 0; i < ne - 1; i++ ) *p++ = MASK_ALL_BITS;
#else
  /* формирование EXONE */
  /* hight part */
  p = exone + ne - 1;
  *p-- = HIGHT_EXONE;
  for( i = 0; i < ne - 1; i++ ) *p-- = MASK_ALL_BITS;
#endif

  /* k = Exponent( fi ) - (EXONE - 1); */
  ei_dece( exone, exone, ne ); /* save (EXONE - 1) */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_sube( k, &fi[1],    exone, ne );
#else
  ei_sube( k, &fi[ns+2], exone, ne );
#endif

  if( ei_cmp0e( k, ne ) <= 0 )
  {
    /* if( Exponent <= 0 ), integer = 0 and
                          real output is fraction */
    for( i = 0; i < nlp; i++ ) lp[i] = (EMUSHORT)0;
    if( frac ) ei_copy( frac, fi, nb );

    /* FREE exone *************/
    /* FREE inc ***************/
    /* FREE k *****************/
    __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE fi ****************/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  for( i = 0; i < ne; i++ ) inc[i] =  (EMUSHORT)0;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  inc[ne-1] = (EMUSHORT)(BITS_PER_EMUSHORT*nlp - 1);
#else
  inc[0]    = (EMUSHORT)(BITS_PER_EMUSHORT*nlp - 1);
#endif
  if( ei_cmpe( k, inc, ne ) > 0 ) /* k > inc */
  {
    /* long INTEGER overflow: output large integer and
                            correct fraction */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    if( fi[0] )
#else
    if( fi[np-1] )
#endif
    {
      /* In this case, return the largest negative INTEGER */
      for( i = 0; i < nlp; i++ ) lp[i] = (EMUSHORT)0;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      lp[0]     = MASK_SIGN;
#else
      lp[nlp-1] = MASK_SIGN;
#endif
    }
    else
    {
#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
      /* In this case, let it overflow and convert as if unsigned */
      ei_rtoul_frac( lp, frac, ei, nlp, nb );

      /* FREE exone *************/
      /* FREE inc ***************/
      /* FREE k *****************/
      __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
      /**************************/

      /* FREE fi ****************/
      __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
#else  /* Not FIXUNS_TRUNC_LIKE_FIX_TRUNC */
      /* In other cases, return the largest positive INTEGER */
      for( i = 0; i < nlp; i++ ) lp[i] = MASK_ALL_BITS;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      lp[0]     ^= MASK_SIGN;
#else
      lp[nlp-1] ^= MASK_SIGN;
#endif
#endif /* FIXUNS_TRUNC_LIKE_FIX_TRUNC */
    } /* End if( Sign ) */

    /* Страховка на случай если
      k > max positive Signed EMUSHORT */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    inc[ne-1] = HIGHT_EXP;
#else
    inc[0]    = HIGHT_EXP;
#endif
    if( ei_cmpe( k, inc, ne ) > 0 )
    {
      ei_shift( fi, (ns+1)*BITS_PER_EMUSHORT, nb );
    }
    else
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      j = k[ne-1];
#else
      j = k[0];
#endif
      ei_shift( fi, j, nb );
    }

    if( __extra_warnings )
    {
      struct __exception  e;

      __real_error_no = __R_ETRUNC__;

      e.who          = _REAL_;
      e.type         = __real_error_no;
      e.name         = (__mpu_char8_t *)"ei_rtol_frac";
      e.msg          = __mpu_utf8mpu_error( _REAL_, __real_error_no );
      e.msg_type     = _WARNING_MSG_;
      e.nb_a1        = 0;
      e.nb_a2        = 0;
      e.nb_rv        = 0;
      e.arg_1        = (unsigned char *)0;
      e.arg_2        = (unsigned char *)0;
      e.return_value = (unsigned char *)0;

      __mpu_warning( &e );

      if( e.msg ) free( e.msg );

    } /* End if( __extra_warnings ) */

  }
  else /* т.е. k <= (BITS_PER_EMUSHORT*nlp - 1); */
  {
    /* NOTE: Здесь k > 0 */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    j = k[ne-1];
#else
    j = k[0];
#endif
    if( j > BITS_PER_EMUSHORT )
    {
      int n;

      n = j % BITS_PER_EMUSHORT;
      ei_shift( fi, n, nb );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      lp[nlp-1] = fi[ne+1]; /* hgw to low part */
#else
      lp[0]     = fi[ns+1];
#endif
      j -= n;
      do
      {
        ei_shup( fi, BITS_PER_EMUSHORT, nb );
        ei_shln( lp, lp, BITS_PER_EMUSHORT, nlp );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
        lp[nlp-1] = fi[ne+1]; /* hgw to low part */
#else
        lp[0]     = fi[ns+1];
#endif
      } while( (j -= BITS_PER_EMUSHORT) > 0 );

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      if( fi[0] )
#else
      if( fi[np-1] )
#endif
        ei_nege( lp, lp, nlp );
    }
    else
    {
      ei_shift( fi, j, nb );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      lp[nlp-1] = fi[ne+1]; /* hgw to low part */
      if( fi[0] )
#else
      lp[0]     = fi[ns+1];
      if( fi[np-1] )
#endif
        ei_nege( lp, lp, nlp );
    }

  } /* End if( k > BITS_PER_EMUSHORT*nlp - 1 ) */


#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  fi[0]    = (EMUSHORT)0;    /* Sign */
  ei_cpye( &fi[1], exone, ne, ne );
  fi[ne+1] = (EMUSHORT)0;    /*  hgw */
#else
  fi[np-1] = (EMUSHORT)0;    /* Sign */
  ei_cpye( &fi[ns+2], exone, ne, ne );
  fi[ns+1] = (EMUSHORT)0;    /*  hgw */
#endif

  /* normalize the Significand */
  if( (j = ei_normalize( fi, nb )) > (__mpu_int32_t)EINSBITS(nb) )
  {
    /* it was zero : это был нуль */
    ei_cleaz( fi, nb );
  }
  else
  {
    ei_cvte_unpack( inc, (EMUSHORT *)&j, ne, 1 );
    /* Exponent -= k; */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    ei_sube( &fi[1],    &fi[1],    inc, ne );
#else
    ei_sube( &fi[ns+2], &fi[ns+2], inc, ne );
#endif
  } /* End of normalize the Significand */

  if( frac ) ei_copy( frac, fi, nb );

  /* FREE exone *************/
  /* FREE inc ***************/
  /* FREE k *****************/
  __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
  /**************************/

  /* FREE fi ****************/
  __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_rtol_frac() */


/***************************************************************
  GENERATORS OF CONSTANT:
 ***************************************************************/

/***************************************************************
  Память адресуемая *EIA должна быть достаточна для размещения
  производимых констант. Чтобы избежать ошибок можно
  воспользоваться макро NPIR_MAX, например:

    unsigned EMUSHORT half[NPIR_MAX];
    _gen_half( half, NBR_256 );

 ***************************************************************/

void _gen_zero( EMUSHORT *eia, int nb )
/****************************************
  0.0;
  zero: Sign 0x0000 hgw 0x0000 ... lgw
 ****************************************/
{
  EMUSHORT *ei = eia; /* = _ei_zero_; */

  ei_signull( ei, (unsigned)0, nb );

} /* End of _gen_zero() */


void _gen_half( EMUSHORT *eia, int nb )
/****************************************
  5.0E-1;
  half: Sign 0x3ffe hgw 0x8000 ... lgw
 ****************************************/
{
  EMUSHORT *ei = eia; /* = _ei_half_; */
  int       i, ne, ns;

  ne = internal_ne( nb );
  ns = internal_ns( nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  ei = ei + ne + ns + 2;   /* начинаем с Sign */
#endif

  *ei = (EMUSHORT)0;                  /* Sign */

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ++ei;
  *ei++ = HIGHT_EXONE;
  for( i = 1; i < ne; i++ ) *ei++ = MASK_ALL_BITS;
  --ei;
  *ei ^= 1; /* Low part of Exponent */
  ++ei;
  *ei++ = (EMUSHORT)0;                 /* hgw */
  *ei++ = MASK_SIGN;         /* с неявной 1.0 */
  for( i = 1; i < ns; i++ ) *ei++ = (EMUSHORT)0;
#else
  --ei;
  *ei-- = HIGHT_EXONE;
  for( i = 1; i < ne; i++ ) *ei-- = MASK_ALL_BITS;
  ++ei;
  *ei ^= 1; /* Low part of Exponent */
  --ei;
  *ei-- = (EMUSHORT)0;                 /* hgw */
  *ei-- = MASK_SIGN;         /* с неявной 1.0 */
  for( i = 1; i < ns; i++ ) *ei-- = (EMUSHORT)0;
#endif

  *ei = (EMUSHORT)0;                   /* lgw */

} /* End of _gen_half() */


void _gen_one( EMUSHORT *eia, int nb )
/****************************************
  1.0E0;
  one:  Sign 0x3fff hgw 0x8000 ... lgw
 ****************************************/
{
  EMUSHORT *ei = eia; /* = _ei_one_; */
  int       i, ne, ns;

  ne = internal_ne( nb );
  ns = internal_ns( nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  ei = ei + ne + ns + 2;   /* начинаем с Sign */
#endif

  *ei = (EMUSHORT)0;                  /* Sign */

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ++ei;
  *ei++ = HIGHT_EXONE;
  for( i = 1; i < ne; i++ ) *ei++ = MASK_ALL_BITS;
  *ei++ = (EMUSHORT)0;                 /* hgw */
  *ei++ = MASK_SIGN;         /* с неявной 1.0 */
  for( i = 1; i < ns; i++ ) *ei++ = (EMUSHORT)0;
#else
  --ei;
  *ei-- = HIGHT_EXONE;
  for( i = 1; i < ne; i++ ) *ei-- = MASK_ALL_BITS;
  *ei-- = (EMUSHORT)0;                 /* hgw */
  *ei-- = MASK_SIGN;         /* с неявной 1.0 */
  for( i = 1; i < ns; i++ ) *ei-- = (EMUSHORT)0;
#endif

  *ei = (EMUSHORT)0;                   /* lgw */

} /* End of _gen_one() */


void _gen_two( EMUSHORT *eia, int nb )
/****************************************
  2.0E0;
  two:  Sign 0x4000 hgw 0x8000 ... lgw
 ****************************************/
{
  EMUSHORT *ei = eia; /* = _ei_two_; */
  int       i, ne, ns;

  ne = internal_ne( nb );
  ns = internal_ns( nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  ei = ei + ne + ns + 2;   /* начинаем с Sign */
#endif

  *ei = (EMUSHORT)0;                  /* Sign */

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ++ei;
  *ei++ = HIGHT_EXTWO;
  for( i = 1; i < ne; i++ ) *ei++ = (EMUSHORT)0;
  *ei++ = (EMUSHORT)0;                 /* hgw */
  *ei++ = MASK_SIGN;         /* с неявной 1.0 */
  for( i = 1; i < ns; i++ ) *ei++ = (EMUSHORT)0;
#else
  --ei;
  *ei-- = HIGHT_EXTWO;
  for( i = 1; i < ne; i++ ) *ei-- = (EMUSHORT)0;
  *ei-- = (EMUSHORT)0;                 /* hgw */
  *ei-- = MASK_SIGN;         /* с неявной 1.0 */
  for( i = 1; i < ns; i++ ) *ei-- = (EMUSHORT)0;
#endif

  *ei = (EMUSHORT)0;                   /* lgw */

} /* End of _gen_two() */


void _gen_ten( EMUSHORT *eia, int nb )
/****************************************
  1.0E1;
  10:   Sign 0x4002 hgw 0xa000 ... lgw
 ****************************************/
{
  EMUSHORT *ei = eia; /* = _ei_ten_; */
  int       i, ne, ns;

  ne = internal_ne( nb );
  ns = internal_ns( nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  ei = ei + ne + ns + 2;   /* начинаем с Sign */
#endif

  *ei = (EMUSHORT)0;                  /* Sign */

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ++ei;
  *ei++ = HIGHT_EXTWO;
  for( i = 1; i < ne; i++ ) *ei++ = (EMUSHORT)0;
  --ei;
  *ei |= 2;           /* Low part of Exponent */
  ++ei;
  *ei++ = (EMUSHORT)0;                 /* hgw */
  *ei++ = HIGHT_M_TEN;       /* с неявной 1.0 */
  for( i = 1; i < ns; i++ ) *ei++ = (EMUSHORT)0;
#else
  --ei;
  *ei-- = HIGHT_EXTWO;
  for( i = 1; i < ne; i++ ) *ei-- = (EMUSHORT)0;
  ++ei;
  *ei |= 2;           /* Low part of Exponent */
  --ei;
  *ei-- = (EMUSHORT)0;                 /* hgw */
  *ei-- = HIGHT_M_TEN;       /* с неявной 1.0 */
  for( i = 1; i < ns; i++ ) *ei-- = (EMUSHORT)0;
#endif

  *ei = (EMUSHORT)0;                   /* lgw */

} /* End of _gen_ten() */


void _gen_mten( EMUSHORT *eia, int nb )
/*********************************************
  1.0E-1;
  0.1:  Sign 0x3ffb hgw 0xcccc ... cccd lgw
 *********************************************/
{
  EMUSHORT *ei = eia; /* = _ei_mten_; */
  int       i, ne, ns;

  ne = internal_ne( nb );
  ns = internal_ns( nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  ei = ei + ne + ns + 2;   /* начинаем с Sign */
#endif

  *ei = (EMUSHORT)0;                  /* Sign */

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ++ei;
  *ei++ = HIGHT_EXONE;
  for( i = 1; i < ne; i++ ) *ei++ = MASK_ALL_BITS;
  --ei;
  *ei ^= 4;           /* Low part of Exponent */
  ++ei;
  *ei++ = (EMUSHORT)0;                 /* hgw */
  *ei++ = HIGHT_M_MTEN;      /* с неявной 1.0 */
  for( i = 1; i < ns; i++ ) *ei++ = HIGHT_M_MTEN;
  --ei;
  *ei |= 1;        /* Low part of Significand */
  ++ei;
#else
  --ei;
  *ei-- = HIGHT_EXONE;
  for( i = 1; i < ne; i++ ) *ei-- = MASK_ALL_BITS;
  ++ei;
  *ei ^= 4;           /* Low part of Exponent */
  --ei;
  *ei-- = (EMUSHORT)0;                 /* hgw */
  *ei-- = HIGHT_M_MTEN;      /* с неявной 1.0 */
  for( i = 1; i < ns; i++ ) *ei-- = HIGHT_M_MTEN;
  ++ei;
  *ei |= 1;        /* Low part of Significand */
  --ei;
#endif

  *ei = (EMUSHORT)0;                   /* lgw */

} /* End of _gen_mten() */


void _gen_32( EMUSHORT *eia, int nb )
/****************************************
  3.2E1;
  32:   Sign 0x4004 hgw 0x8000 ... lgw
 ****************************************/
{
  EMUSHORT *ei = eia; /* = _ei_32_; */
  int       i, ne, ns;

  ne = internal_ne( nb );
  ns = internal_ns( nb );

#if MPU_WORD_ORDER_BIG_ENDIAN == 0
  ei = ei + ne + ns + 2;   /* начинаем с Sign */
#endif

  *ei = (EMUSHORT)0;                  /* Sign */

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ++ei;
  *ei++ = HIGHT_EXTWO;
  for( i = 1; i < ne; i++ ) *ei++ = (EMUSHORT)0;
  --ei;
  *ei |= 4;           /* Low part of Exponent */
  ++ei;
  *ei++ = (EMUSHORT)0;                 /* hgw */
  *ei++ = MASK_SIGN;         /* с неявной 1.0 */
  for( i = 1; i < ns; i++ ) *ei++ = (EMUSHORT)0;
#else
  --ei;
  *ei-- = HIGHT_EXTWO;
  for( i = 1; i < ne; i++ ) *ei-- = (EMUSHORT)0;
  ++ei;
  *ei |= 4;           /* Low part of Exponent */
  --ei;
  *ei-- = (EMUSHORT)0;                 /* hgw */
  *ei-- = MASK_SIGN;         /* с неявной 1.0 */
  for( i = 1; i < ns; i++ ) *ei-- = (EMUSHORT)0;
#endif

  *ei = (EMUSHORT)0;                   /* lgw */

} /* End of _gen_32() */

/***************************************************************
  END GENERATORS OF CONSTANT.
 ***************************************************************/


void ei_remain( EMUSHORT *eic, EMUSHORT *eiquot, EMUSHORT *eia, EMUSHORT *eib, int nb )
/***************************************************************

 Description        : ei_remain() Работает с
                                  internal e-type data struct.

 Concepts           : EIC = remainder after dividing EIA by EIB.
                      Sign of remainder == Sign of quotient.
                      If( EIQUOT != (EMUSHORT *)0 )
                      {
                        RETURN quotient of exploded
                        e-types EIA / EIB as unsigned
                        integer number in EIQUOT.
                      }

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         :
                      EMUSHORT *eic;    - указатель на
                                          internal e-type
                                          data struct.
                                          TARGET REMAINDER;
                      EMUSHORT *eiquot; - указатель на
                                          internal e-type
                                          data struct.
                                          TARGET QUOTIENT;
                      EMUSHORT *eia;    - указатель на
                                          internal e-type
                                          data struct.
                      EMUSHORT *eib;    - указатель на
                                          internal e-type
                                          data struct.
                      int nb;           - количество бит в
                                          external e-type
                                          data struct;
                                          EIA, EIB, EIC &
                                          EIQUOT.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT         *ld = NULL,
                   *ln = NULL,
                  *inc = NULL,
                  *den = NULL,
                  *num = NULL,
                *equot = NULL,
                 *zero = NULL;
  EMUSHORT      *p;
  EMUSHORT       j;
  __mpu_int32_t  k;
  int            np, ne, ns;

  if( nb < NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );


  if( ei_isinfin( eia, nb ) )
  {
    ei_nan( eic, 0, nb );
    return;
  }

  /*** Allocate memory for den, num . *************************/
  den = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !den )
  {
    /* fatal error */
    return;
  }

  num = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !num )
  {
    /* fatal error */

    /* FREE den ***************/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  ei_copy( num, eia, nb );
  ei_copy( den, eib, nb );

  /* EIA */
  /* InD plus anything is a InD */
  if( ei_isind( eia, nb ) )
  {
    /* "invalid operation" */
    ei_copy( eic, eia, nb );
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( eic, (__mpu_char8_t *)"remain", __INVALID__, eic, num, den, nb );
    __STIND; /* Set REAL ind-produsing operation Flag */

    /* FREE den ***************/
    /* FREE num ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /* NaN plus anything is a NaN */
  if( ei_isnans( eia, nb ) )
  {
    ei_copy( eic, eia, nb );

    /* FREE den ***************/
    /* FREE num ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  /* EIB */
  /* InD plus anything is a InD */
  if( ei_isind( eib, nb ) )
  {
    /* "invalid operation" */
    ei_copy( eic, eib, nb );
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( eic, (__mpu_char8_t *)"remain", __INVALID__, eic, num, den, nb );
    __STIND; /* Set REAL ind-produsing operation Flag */

    /* FREE den ***************/
    /* FREE num ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /* NaN plus anything is a NaN */
  if( ei_isnans( eib, nb ) )
  {
    ei_copy( eic, eib, nb );

    /* FREE den ***************/
    /* FREE num ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  /*** Allocate memory for zero . *****************************/
  zero = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !zero )
  {
    /* fatal error */

    /* FREE den ***************/
    /* FREE num ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  _gen_zero( zero, nb ); /* for zero[NPIR_MAX] */

  if( ei_cmp( eib, zero, nb ) == 0 )
  {
    ei_cleaz( eic, nb );
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( eic, (__mpu_char8_t *)"remain", __SING__, eic, num, den, nb );
    __STSNG; /* Set REAL Singularity Flag */

    /* FREE den ***************/
    /* FREE num ***************/
    /* FREE zero **************/
    __mpu_sbrk( -(int)(3*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  /*** Allocate memory for equot, inc, ln, ld . ***************/
  equot = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !equot )
  {
    /* fatal error */

    /* FREE den ***************/
    /* FREE num ***************/
    /* FREE zero **************/
    __mpu_sbrk( -(int)(3*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE den ***************/
    /* FREE num ***************/
    /* FREE zero **************/
    /* FREE equot *************/
    __mpu_sbrk( -(int)(4*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  ln = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !ln )
  {
    /* fatal error */

    /* FREE den ***************/
    /* FREE num ***************/
    /* FREE zero **************/
    /* FREE equot *************/
    __mpu_sbrk( -(int)(4*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE inc ***************/
    __mpu_sbrk( -(int)((ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  ld = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !ld )
  {
    /* fatal error */

    /* FREE den ***************/
    /* FREE num ***************/
    /* FREE zero **************/
    /* FREE equot *************/
    __mpu_sbrk( -(int)(4*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE inc ***************/
    /* FREE ln ****************/
    __mpu_sbrk( -(int)(2*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/


  /* Copy Exponents */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( ln, &num[1],    ne+1, ne );
  ei_cpye_unpack( ld, &den[1],    ne+1, ne );
#else
  ei_cpye_unpack( ln, &num[ns+2], ne+1, ne );
  ei_cpye_unpack( ld, &den[ns+2], ne+1, ne );
#endif

  k = ei_normalize( num, nb );
  ei_cvte_unpack( inc, (EMUSHORT *)&k, ne+1, 1 );
  ei_sube( ln, ln, inc, ne+1 );

  k = ei_normalize( den, nb );
  ei_cvte_unpack( inc, (EMUSHORT *)&k, ne+1, 1 );
  ei_sube( ld, ld, inc, ne+1 );

  ei_cleaz( equot, nb );

  /* Set *p to low part of Significand */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p = &equot[np - 1];
#else
  p = &equot[0];
#endif

  while( ei_cmpe( ln, ld, ne+1 ) >= 0 ) /* ( ln >= ld ) */
  {
    if( ei_cmpm( den, num, nb ) <= 0 )
    {
      ei_subm( num, num, den, nb );
      j = (EMUSHORT)1;
    }
    else
      j = (EMUSHORT)0;

    ei_shup( equot, (unsigned)1, nb );
    *p |= j;
    ei_shup( num,   (unsigned)1, nb );
    ei_dece( ln, ln, ne+1 );

  } /* End while( ln >= ld ) */

  ei_mdenorm( num, 0, 0, ln, 0, nb );

  /* Sign of remainder == Sign of quotient */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  if( eia[0] == eib[0] ) num[0] = (EMUSHORT)0;
  else                   num[0] = MASK_ALL_BITS;
#else
  if( eia[np-1] == eib[np-1] ) num[np-1] = (EMUSHORT)0;
  else                         num[np-1] = MASK_ALL_BITS;
#endif

  if( eiquot ) ei_copy( eiquot, equot, nb );

  ei_copy( eic, num, nb );

  /* FREE den ***************/
  /* FREE num ***************/
  /* FREE zero **************/
  /* FREE equot *************/
  __mpu_sbrk( -(int)(4*np*SIZE_OF_EMUSHORT) );
  /**************************/

  /* FREE inc ***************/
  /* FREE ln ****************/
  /* FREE ld ****************/
  __mpu_sbrk( -(int)(3*(ne+1)*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_remain() */


#if BITS_PER_EMUSHORT == 16
static EMUSHORT bitmask[] =
{
  0xffff,
  0xfffe,
  0xfffc,
  0xfff8,
  0xfff0,
  0xffe0,
  0xffc0,
  0xff80,
  0xff00,
  0xfe00,
  0xfc00,
  0xf800,
  0xf000,
  0xe000,
  0xc000,
  0x8000,
  0x0000,
};
#else /* not (BITS_PER_EMUSHORT == 16) */
#if BITS_PER_EMUSHORT == 32
static EMUSHORT bitmask[] =
{
  0xffffffff,
  0xfffffffe,
  0xfffffffc,
  0xfffffff8,
  0xfffffff0,
  0xffffffe0,
  0xffffffc0,
  0xffffff80,
  0xffffff00,
  0xfffffe00,
  0xfffffc00,
  0xfffff800,
  0xfffff000,
  0xffffe000,
  0xffffc000,
  0xffff8000,
  0xffff0000,
  0xfffe0000,
  0xfffc0000,
  0xfff80000,
  0xfff00000,
  0xffe00000,
  0xffc00000,
  0xff800000,
  0xff000000,
  0xfe000000,
  0xfc000000,
  0xf8000000,
  0xf0000000,
  0xe0000000,
  0xc0000000,
  0x80000000,
  0x00000000,
};
#else /* not (BITS_PER_EMUSHORT == 32) */
#if BITS_PER_EMUSHORT == 64
static EMUSHORT bitmask[] =
{
  0xffffffffffffffff,
  0xfffffffffffffffe,
  0xfffffffffffffffc,
  0xfffffffffffffff8,
  0xfffffffffffffff0,
  0xffffffffffffffe0,
  0xffffffffffffffc0,
  0xffffffffffffff80,
  0xffffffffffffff00,
  0xfffffffffffffe00,
  0xfffffffffffffc00,
  0xfffffffffffff800,
  0xfffffffffffff000,
  0xffffffffffffe000,
  0xffffffffffffc000,
  0xffffffffffff8000,
  0xffffffffffff0000,
  0xfffffffffffe0000,
  0xfffffffffffc0000,
  0xfffffffffff80000,
  0xfffffffffff00000,
  0xffffffffffe00000,
  0xffffffffffc00000,
  0xffffffffff800000,
  0xffffffffff000000,
  0xfffffffffe000000,
  0xfffffffffc000000,
  0xfffffffff8000000,
  0xfffffffff0000000,
  0xffffffffe0000000,
  0xffffffffc0000000,
  0xffffffff80000000,
  0xffffffff00000000,
  0xfffffffe00000000,
  0xfffffffc00000000,
  0xfffffff800000000,
  0xfffffff000000000,
  0xffffffe000000000,
  0xffffffc000000000,
  0xffffff8000000000,
  0xffffff0000000000,
  0xfffffe0000000000,
  0xfffffc0000000000,
  0xfffff80000000000,
  0xfffff00000000000,
  0xffffe00000000000,
  0xffffc00000000000,
  0xffff800000000000,
  0xffff000000000000,
  0xfffe000000000000,
  0xfffc000000000000,
  0xfff8000000000000,
  0xfff0000000000000,
  0xffe0000000000000,
  0xffc0000000000000,
  0xff80000000000000,
  0xff00000000000000,
  0xfe00000000000000,
  0xfc00000000000000,
  0xf800000000000000,
  0xf000000000000000,
  0xe000000000000000,
  0xc000000000000000,
  0x8000000000000000,
  0x0000000000000000,
};
#else /* not (BITS_PER_EMUSHORT == 64) */
#error mpu-real.c: Cannot use that size of EMUSHORT type 
#endif /* BITS_PER_EMUSHORT == 64 */
#endif /* BITS_PER_EMUSHORT == 32 */
#endif /* BITS_PER_EMUSHORT == 16 */


void ei_floor( EMUSHORT *eic, EMUSHORT *eia, int nb )
/***************************************************************

 Description        : ei_floor() Работает с
                                 internal e-type data struct.

 Concepts           : Return EIC = largest integer not greater
                      than EIA (truncated toward minus
                      infinity).
                      Возвращает EIC = наиболшее (ближайшее)
                      целое не большее чем EIA (срезает в
                      сторону минус бесконечности).

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         :
                      EMUSHORT *eic; - указатель на
                                       internal e-type
                                       data struct.
                                       TARGET FLOOR;
                      EMUSHORT *eia; - указатель на
                                       internal e-type
                                       data struct.
                                       SOURCE;
                      int nb;        - количество бит в
                                       external e-type
                                       data struct;
                                       EIA, & EIC.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT      *exone = NULL,
                  *exp = NULL,
                  *inc = NULL,
                   *fi = NULL,
                  *num = NULL,
                *equot = NULL,
                  *one = NULL;
  EMUSHORT      *p, *q;
  EMUSHORT       j;
  __mpu_int32_t  e;
  int            np, ne, ns, i;

  if( nb < NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  /* Если на входе знаковый ноль. */
  if( ei_issignull( eia, nb ) )
  {
    ei_copy( eic, eia, nb );
    return;
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for exone, exp, inc . ******************/
  exone = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !exone )
  {
    /* fatal error */
    return;
  }

  exp = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !exp )
  {
    /* fatal error */

    /* FREE exone *************/
    __mpu_sbrk( -(int)(ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE exp ***************/
    __mpu_sbrk( -(int)(2*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  /*** Allocate memory for fi, num, equot,one . ***************/
  fi = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !fi )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE exp ***************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  num = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !num )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE exp ***************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE fi ****************/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  equot = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !equot )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE exp ***************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE fi ****************/
    /* FREE num ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  one = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !one )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE exp ***************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE fi ****************/
    /* FREE num ***************/
    /* FREE equot *************/
    __mpu_sbrk( -(int)(3*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  ei_copy( fi, eia, nb );

  /* Copy Exponents */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye( exp, &fi[1],    ne, ne );
#else
  ei_cpye( exp, &fi[ns+2], ne, ne );
#endif

  /* Create EXONE */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* hight part */
  p = exone;
  *p++ = HIGHT_EXONE; /* 0x3fff... */
  for( i = 0; i < ne - 1; i++ ) *p++ = MASK_ALL_BITS;
#else
  /* hight part */
  p = exone + ne - 1;
  *p-- = HIGHT_EXONE;
  for( i = 0; i < ne - 1; i++ ) *p-- = MASK_ALL_BITS;
#endif

  ei_dece( exone, exone, ne );
  ei_sube( exp, exp, exone, ne );

  if( ei_cmp0e( exp, nb ) <= 0 ) /* ( exp <= 0 ) */
  {
    ei_cleaz( eic, nb );
    goto isitminus;
  }

  /* Формируем INC как количество бит мантиссы. */
  for( i = 0; i < ne; i++ ) inc[i] = (EMUSHORT)0;
  j = EINSBITS(nb);
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  inc[ne-1] = j;
#else
  inc[0]    = j;
#endif

  ei_sube( exp, inc, exp, ne );

  ei_copy( eic, fi, nb );
  if( ei_cmp0e( exp, ne ) <= 0 ) /* ( exp <= 0 ) */
  {
    /* FREE exone *************/
    /* FREE exp ***************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE fi ****************/
    /* FREE num ***************/
    /* FREE equot *************/
    /* FREE one ***************/
    __mpu_sbrk( -(int)(4*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p = &eic[ne+ns+2]; /* lgw */
  *p-- = (EMUSHORT)0; /* p -> low part of Significand */
#else
  p = &eic[0];       /* lgw */
  *p++ = (EMUSHORT)0; /* p -> low part of Significand */
#endif

  /* Следующее действие правомерно, т.к. количество бит мантиссы
     укладывается в число типа signed EMUSHORT. */
  ei_cpye_pack( (EMUSHORT *)(&e), exp, 1, ne );

  while( e >= BITS_PER_EMUSHORT )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    *p-- = (EMUSHORT)0;
#else
    *p++ = (EMUSHORT)0;
#endif
    e -= BITS_PER_EMUSHORT;
  }

  /* Clear the remaining bits. */
  *p &= bitmask[e];

  /* Truncate negatives toward minus infinity. */
isitminus:

  if( ei_isneg( fi, nb ) )
  {
    _gen_one( one, nb );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    q = &eic[ne+ns+1]; /* low part of Signoficand */
    p =  &fi[ne+ns+1];
#else
    q = &eic[1];       /* low part of Signoficand */
    p =  &fi[1];
#endif

    for( i = 0; i < ns; i++ )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      if( *p-- != *q-- )
#else
      if( *p++ != *q++ )
#endif
      {
        ei_sub( eic, eic, one, nb );
        break;
      }

    } /* End for( all parts of Significand ) */

  } /* End if( isneg(fi) ) */

  /* FREE exone *************/
  /* FREE exp ***************/
  /* FREE inc ***************/
  __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
  /**************************/

  /* FREE fi ****************/
  /* FREE num ***************/
  /* FREE equot *************/
  /* FREE one ***************/
  __mpu_sbrk( -(int)(4*np*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_floor() */


void ei_ceil( EMUSHORT *eic, EMUSHORT *eia, int nb )
/***************************************************************

 Description        : ei_ceil() Работает с
                                internal e-type data struct.

 Concepts           : Return EIC = neargest integer not smaller
                      than EIA (truncated toward plus infinity).
                      Возвращает EIC = наименьшее (ближайшее)
                      целое не меньшее чем EIA (срезает в
                      сторону плюс бесконечности).

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         :
                      EMUSHORT *eic; - указатель на
                                       internal e-type
                                       data struct.
                                       TARGET CEIL;
                      EMUSHORT *eia; - указатель на
                                       internal e-type
                                       data struct.
                                       SOURCE;
                      int nb;        - количество бит в
                                       external e-type
                                       data struct;
                                       EIA, & EIC.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT      *exone = NULL,
                  *exp = NULL,
                  *inc = NULL,
                   *fi = NULL,
                  *num = NULL,
                *equot = NULL,
                  *one = NULL;
  EMUSHORT      *p, *q;
  EMUSHORT       j;
  __mpu_int32_t  e;
  int            np, ne, ns, i;

  if( nb < NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  /* Если на входе знаковый ноль. */
  if( ei_issignull( eia, nb ) )
  {
    ei_copy( eic, eia, nb );
    return;
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for exone, exp, inc . ******************/
  exone = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !exone )
  {
    /* fatal error */
    return;
  }

  exp = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !exp )
  {
    /* fatal error */

    /* FREE exone *************/
    __mpu_sbrk( -(int)(ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE exp ***************/
    __mpu_sbrk( -(int)(2*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  /*** Allocate memory for fi, num, equot,one . ***************/
  fi = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !fi )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE exp ***************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  num = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !num )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE exp ***************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE fi ****************/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  equot = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !equot )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE exp ***************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE fi ****************/
    /* FREE num ***************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  one = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !one )
  {
    /* fatal error */

    /* FREE exone *************/
    /* FREE exp ***************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE fi ****************/
    /* FREE num ***************/
    /* FREE equot *************/
    __mpu_sbrk( -(int)(3*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  ei_copy( fi, eia, nb );

  /* Copy Exponents */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye( exp, &fi[1],    ne, ne );
#else
  ei_cpye( exp, &fi[ns+2], ne, ne );
#endif

  /* Create EXONE */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* hight part */
  p = exone;
  *p++ = HIGHT_EXONE; /* 0x3fff... */
  for( i = 0; i < ne - 1; i++ ) *p++ = MASK_ALL_BITS;
#else
  /* hight part */
  p = exone + ne - 1;
  *p-- = HIGHT_EXONE;
  for( i = 0; i < ne - 1; i++ ) *p-- = MASK_ALL_BITS;
#endif

  ei_dece( exone, exone, ne );
  ei_sube( exp, exp, exone, ne );

  if( ei_cmp0e( exp, nb ) <= 0 ) /* ( exp <= 0 ) */
  {
    ei_cleaz( eic, nb );
    goto isitplus;
  }

  /* Формируем INC как количество бит мантиссы. */
  for( i = 0; i < ne; i++ ) inc[i] = (EMUSHORT)0;
  j = EINSBITS(nb);
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  inc[ne-1] = j;
#else
  inc[0]    = j;
#endif

  ei_sube( exp, inc, exp, ne );

  ei_copy( eic, fi, nb );
  if( ei_cmp0e( exp, ne ) <= 0 ) /* ( exp <= 0 ) */
  {
    /* FREE exone *************/
    /* FREE exp ***************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE fi ****************/
    /* FREE num ***************/
    /* FREE equot *************/
    /* FREE one ***************/
    __mpu_sbrk( -(int)(4*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p = &eic[ne+ns+2]; /* lgw */
  *p-- = (EMUSHORT)0; /* p -> low part of Significand */
#else
  p = &eic[0];       /* lgw */
  *p++ = (EMUSHORT)0; /* p -> low part of Significand */
#endif

  /* Следующее действие правомерно, т.к. количество бит мантиссы
     укладывается в число типа signed EMUSHORT. */
  ei_cpye_pack( (EMUSHORT *)(&e), exp, 1, ne );

  while( e >= BITS_PER_EMUSHORT )
  {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    *p-- = (EMUSHORT)0;
#else
    *p++ = (EMUSHORT)0;
#endif
    e -= BITS_PER_EMUSHORT;
  }

  /* Clear the remaining bits. */
  *p &= bitmask[e];

  /* Truncate positives toward plus infinity. */
isitplus:

  if( !ei_isneg( fi, nb ) )
  {
    _gen_one( one, nb );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    q = &eic[ne+ns+1]; /* low part of Signoficand */
    p =  &fi[ne+ns+1];
#else
    q = &eic[1];       /* low part of Signoficand */
    p =  &fi[1];
#endif

    for( i = 0; i < ns; i++ )
    {
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      if( *p-- != *q-- )
#else
      if( *p++ != *q++ )
#endif
      {
        ei_add( eic, eic, one, nb );
        break;
      }

    } /* End for( all parts of Significand ) */

  } /* End if( !isneg(fi) ) */

  /* FREE exone *************/
  /* FREE exp ***************/
  /* FREE inc ***************/
  __mpu_sbrk( -(int)(3*ne*SIZE_OF_EMUSHORT) );
  /**************************/

  /* FREE fi ****************/
  /* FREE num ***************/
  /* FREE equot *************/
  /* FREE one ***************/
  __mpu_sbrk( -(int)(4*np*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_ceil() */


void ei_round( EMUSHORT *eic, EMUSHORT *eia, int nb )
/***************************************************************

 Description        : ei_round() Работает с
                                 internal e-type data struct.

 Concepts           : Return EIC = nearest integer to EIA,
                      as FLOOR( EIA + 0.5 ).

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file

 Parameters         :
                      EMUSHORT *eic; - указатель на
                                       internal e-type
                                       data struct.
                                       TARGET CEIL;
                      EMUSHORT *eia; - указатель на
                                       internal e-type
                                       data struct.
                                       SOURCE;
                      int nb;        - количество бит в
                                       external e-type
                                       data struct;
                                       EIA, & EIC.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT *half = NULL;
  int       np;

  if( nb < NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  np = internal_np( nb );

  /*** Allocate memory for half . *****************************/
  half = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !half )
  {
    /* fatal error */
    return;
  }
  /************************************************************/


  _gen_half( half, nb );
  ei_add( eic, eia, half, nb );
  ei_floor( eic, eic, nb );


  /* FREE half **************/
  __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_round() */


void ei_frexp( EMUSHORT *eis, EMUSHORT *lpexp, EMUSHORT *eia, int nlp, int nb )
/***************************************************************

 Description        : ei_frexp() Работает с
                                 internal e-type data struct.

 Concepts           : Return EIS and LPEXP such that
                      EIS * 2^LPEXP = EIA and 0.5 <= EIS < 1.0.
                      For example, 1.1 = 0.55 * 2^1.
                      =========================================
                      Функция разбивает число EIA на мантиссу
                      EIS и экспоненту LPEXP таким образом,
                      что абсолютное значение EIS больше или
                      равно 0.5 и меньше 1.0 и
                      EIA == EIS * 2^LPEXP.
                      Например, 1.1 = 0.55 * 2^1.

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         :
                      EMUSHORT *eis;   - указатель на
                                         internal e-type
                                         data struct.
                                         TARGET Significand;
                      EMUSHORT *lpexp; - указатель на
                                         external long
                                         INTEGER number.
                                         TARGET EXP;
                      EMUSHORT *eia;   - указатель на
                                         internal e-type
                                         data struct.
                                         SOURCE;
                      int nlp;         - количество порций
                                         размера EMUSHORT в
                                         external long
                                         INTEGER number;
                                         LPEXP.
                      NOTE:
                      =========================================
                       NLP должно быть не меньше количества
                       порций размера EMUSHORT в
                       Exponent( EIA ), т.е.
                                  nlp >= internal_ne(nb);
                       ВНИМАНИЕ:
                          При использовании данной функции
                          программист обязан самостоятельно
                          отслеживать размер памяти,
                          выделяемой под LPEXP.
                      =========================================

                      int nb;          - количество бит в
                                         external e-type
                                         data struct;
                                         EIA, & EIS.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT      *exp = NULL,
                *inc = NULL,
                 *xi = NULL;
  EMUSHORT      *p;
  __mpu_int32_t  j;
  int            np, ne, ns, i;

  if( nb < NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  if( nlp < ne )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  /*** Allocate memory for exp, inc, xi . *********************/
  exp = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !exp )
  {
    /* fatal error */
    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)(ne*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE exp ***************/
    __mpu_sbrk( -(int)(ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  xi = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !xi )
  {
    /* fatal error */

    /* FREE exp ***************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(2*ne*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  ei_copy( xi, eia, nb );

  /*
    Handle denormalized numbers properly using long integer exponent.
   */

  /* Copy Exponents */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( exp, &xi[1],    ne, ne );
#else
  ei_cpye_unpack( exp, &xi[ns+2], ne, ne );
#endif

  if( ei_cmp0e( exp, ne ) == 0 ) /* ( exp == 0 ) */
  {
    /* exp -= ei_normalize( xi ); */
    j = ei_normalize( xi, nb );
    ei_cpye_unpack( inc, (EMUSHORT *)&j, ne, 1 );
    ei_sube( exp, exp, inc, ne );
  }

  /* Формирование HALF (экспоненты 0.5) */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p = &inc[0];    /* hight part of Exponent */
  *p++ = HIGHT_EXONE;
  for( i = 1; i < ne; i++ ) *p++ = MASK_ALL_BITS;
  --p;
  *p ^= 1; /* Low part of Exponent */
#else
  p = &inc[ne-1]; /* hight part of Exponent */
  *p-- = HIGHT_EXONE;
  for( i = 1; i < ne; i++ ) *p-- = MASK_ALL_BITS;
  ++p;
  *p ^= 1; /* Low part of Exponent */
#endif

  /* Copy Exponents */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( &xi[1],    inc, ne, ne );
#else
  ei_cpye_unpack( &xi[ns+2], inc, ne, ne );
#endif

  ei_copy( eis, xi, nb );

  ei_sube( exp, exp, inc, ne );

  ei_cpye_unpack( lpexp, exp, nlp, ne );

  /* FREE exp ***************/
  /* FREE inc ***************/
  __mpu_sbrk( -(int)(2*ne*SIZE_OF_EMUSHORT) );
  /**************************/

  /* FREE xi ****************/
  __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_frexp() */


void ei_ldexp( EMUSHORT *eic, EMUSHORT *lppwr2, EMUSHORT *eia, int nlp, int nb )
/***************************************************************

 Description        : ei_ldexp() Работает с
                                 internal e-type data struct.

 Concepts           : Return EIC = EIA * 2^PWR2.
                      =========================================
                      Функция вычисляет значение EIC как
                      EIA умноженное на 2 в степени LPPWR2.

 Use Global Variable:

 Use Functions      :
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         :
                      EMUSHORT *eic;    - указатель на
                                          internal e-type
                                          data struct.
                                          TARGET;
                      EMUSHORT *lppwr2; - указатель на
                                          external long
                                          INTEGER number.
                                          SOURCE PWR2;
                      EMUSHORT *eia;    - указатель на
                                          internal e-type
                                          data struct.
                                          SOURCE;
                      int nlp;          - количество порций
                                          размера EMUSHORT в
                                          external long
                                          INTEGER number;
                                          LPPWR2.
                      NOTE:
                      =========================================
                       NLP должно быть не больше количества
                       порций размера EMUSHORT в
                       Exponent( EIA )+1, т.е.
                                  nlp <= internal_ne(nb)+1;
                       ВНИМАНИЕ:
                          При использовании данной функции
                          программист обязан самостоятельно
                          отслеживать размер памяти,
                          выделяемой под LPPWR2.
                      =========================================

                      int nb;           - количество бит в
                                          external e-type
                                          data struct;
                                          EIA, & EIC.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT *exp = NULL,
           *inc = NULL,
            *xi = NULL;
  int       np, ne, ns;

  if( nb < NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  if( nlp > ne+1 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  /*** Allocate memory for exp, inc, xi . *********************/
  exp = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !exp )
  {
    /* fatal error */
    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE exp ***************/
    __mpu_sbrk( -(int)((ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  xi = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !xi )
  {
    /* fatal error */

    /* FREE exp ***************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(2*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  ei_copy( xi, eia, nb );

  /* Copy Exponents */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( exp, &xi[1],    ne+1, ne );
#else
  ei_cpye_unpack( exp, &xi[ns+2], ne+1, ne );
#endif

  /* Copy PWR2 */
  ei_cpye_unpack( inc, lppwr2, ne+1, nlp );

  /* exp += pwr2 */
  ei_adde( exp, exp, inc, ne+1 );

  ei_mdenorm( xi, 0, 0, exp, 0, nb ); /* rcntrl = 0 (просто обнуляем lgw) */

  ei_copy( eic, xi, nb );

  /* FREE exp ***************/
  /* FREE inc ***************/
  __mpu_sbrk( -(int)(2*(ne+1)*SIZE_OF_EMUSHORT) );
  /**************************/

  /* FREE xi ****************/
  __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_ldexp() */


void ei_logb( EMUSHORT *lpbase2, EMUSHORT *eia, int nlp, int nb )
/***************************************************************

 Description        : ei_logb() Работает с
                                internal e-type data struct.

 Concepts           : Return LPbase2 = the base 2 signed
                                       integral Exponent of
                                       EIA.
                      =========================================
                      Функция вычисляет значение LPbase2 как
                      знаковую интегральную экспоненту по
                      основанию 2 вещественного числа EIA.

 Use Global Variable:

 Use Functions      :
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         :
                      EMUSHORT *lpbase2; - указатель на
                                           external long
                                           INTEGER number.
                                           TARGET;
                      EMUSHORT *eia;     - указатель на
                                           internal e-type
                                           data struct.
                                           SOURCE;
                      int nlp;           - количество порций
                                           размера EMUSHORT в
                                           external long
                                           INTEGER number;
                                           LPBASE2.
                      NOTE:
                      =========================================
                       NLP должно быть БОЛЬШЕ или равно
                       количеству порций размера EMUSHORT в
                       Exponent( EIA )+1, т.е.
                          nlp >= internal_ne(nb)+1;
                       ВНИМАНИЕ:
                          При использовании данной функции
                          программист обязан самостоятельно
                          отслеживать размер памяти,
                          выделяемой под LPBASE2.
                      =========================================

                      int nb;           - количество бит в
                                          external e-type
                                          data struct;
                                          EIA.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT   *exp = NULL,
           *base2 = NULL,
           *exone = NULL,
            *pwr2 = NULL,
             *inc = NULL,
              *xi = NULL,
            *zero = NULL,
             *one = NULL,
              *ti = NULL;
  EMUSHORT *p;
  EMUSHORT  n_mant_bits = EINSBITS(nb);
  int       np, ne, ns, i;

  if( nb < NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  if( nlp < ne+1 )
  {
    /* fatal error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  /*** Allocate memory for xi . *******************************/
  xi = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !xi )
  {
    /* fatal error */
    return;
  }
  /************************************************************/

  ei_copy( xi, eia, nb );

  /***************************
    Test for EIA.
   ***************************/
  /* EI_LOGB(InD) produsing Domain Flag */
  if( ei_isind( eia, nb ) )
  {
    /* "argument domain error" */
    /* return: ZERO */
    for( i = 0; i < nlp; i++ ) lpbase2[i] = (EMUSHORT)0;
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( (EMUSHORT *)0, /* not change */
           (__mpu_char8_t *)"logb", __DOMAIN__, (EMUSHORT *)0,
           xi, (EMUSHORT *)0, nb );
    __STDOM; /* Set REAL InD - produsing Domain Flag */

    /* FREE xi ****************/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /* EI_LOGB(NaN) produsing Domain Flag */
  if( ei_isnans( eia, nb ) )
  {
    /* "argument domain error" */
    /* return: ZERO */
    for( i = 0; i < nlp; i++ ) lpbase2[i] = (EMUSHORT)0;
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( (EMUSHORT *)0, /* not change */
           (__mpu_char8_t *)"logb", __DOMAIN__, (EMUSHORT *)0,
           xi, (EMUSHORT *)0, nb );
    __STDOM; /* Set REAL NaN - produsing Domain Flag */

    /* FREE xi ****************/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  /* EI_LOGB(Infinity) produsing Domain Flag */
  if( ei_isinfin( eia, nb ) )
  {
    /* "argument domain error" */
    /* return: ZERO */
    for( i = 0; i < nlp; i++ ) lpbase2[i] = (EMUSHORT)0;
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( (EMUSHORT *)0, /* not change */
           (__mpu_char8_t *)"logb", __DOMAIN__, (EMUSHORT *)0,
           xi, (EMUSHORT *)0, nb );
    __STDOM; /* Set REAL Infinity - produsing Domain Flag */

    /* FREE xi ****************/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  /*** Allocate memory for zero . *****************************/
  zero = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !zero )
  {
    /* fatal error */

    /* FREE xi ****************/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  _gen_zero( zero, nb );

  /* EI_LOGB(0.0) produsing Domain Flag */
  if( ei_cmp( zero, eia, nb ) == 0 )
  {
    /* "argument domain error" */
    /* return: ZERO */
    for( i = 0; i < nlp; i++ ) lpbase2[i] = (EMUSHORT)0;
    /***************************************************
      NOTE:
        Функция _mtherr() является переходником между
        внутренним форматом и внешней,
        переопределяемой пользователем, функцией
        __mpu_math_error(). Кроме основных действий
        она выставляет системную переменную errno
        следующим образом.

          errno = __mpu_math_errnotab[type];
     ***************************************************/
    _mtherr( (EMUSHORT *)0, /* not change */
           (__mpu_char8_t *)"logb", __DOMAIN__, (EMUSHORT *)0,
           xi, (EMUSHORT *)0, nb );
    __STDOM; /* Set REAL (EIA == 0.0) - produsing Domain Flag */

    /* FREE xi ****************/
    /* FREE zero **************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  /*** Allocate memory for one . ******************************/
  one = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !one )
  {
    /* fatal error */

    /* FREE xi ****************/
    /* FREE zero **************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  _gen_one( one, nb );

  /*** Allocate memory for ti, exp, base2, exone, pwr2, inc . */
  ti = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !ti )
  {
    /* fatal error */

    /* FREE xi ****************/
    /* FREE zero **************/
    /* FREE one ***************/
    __mpu_sbrk( -(int)(3*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  exp = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !exp )
  {
    /* fatal error */

    /* FREE xi ****************/
    /* FREE zero **************/
    /* FREE one ***************/
    /* FREE ti ****************/
    __mpu_sbrk( -(int)(4*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  base2 = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !base2 )
  {
    /* fatal error */

    /* FREE xi ****************/
    /* FREE zero **************/
    /* FREE one ***************/
    /* FREE ti ****************/
    __mpu_sbrk( -(int)(4*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE exp ***************/
    __mpu_sbrk( -(int)((ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  exone = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !exone )
  {
    /* fatal error */

    /* FREE xi ****************/
    /* FREE zero **************/
    /* FREE one ***************/
    /* FREE ti ****************/
    __mpu_sbrk( -(int)(4*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE exp ***************/
    /* FREE base2 *************/
    __mpu_sbrk( -(int)(2*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  pwr2 = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !pwr2 )
  {
    /* fatal error */

    /* FREE xi ****************/
    /* FREE zero **************/
    /* FREE one ***************/
    /* FREE ti ****************/
    __mpu_sbrk( -(int)(4*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE exp ***************/
    /* FREE base2 *************/
    /* FREE exone *************/
    __mpu_sbrk( -(int)(3*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE xi ****************/
    /* FREE zero **************/
    /* FREE one ***************/
    /* FREE ti ****************/
    __mpu_sbrk( -(int)(4*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE exp ***************/
    /* FREE base2 *************/
    /* FREE exone *************/
    /* FREE pwr2 **************/
    __mpu_sbrk( -(int)(4*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  /* Generate the EXONE */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  /* hight part */
  p = exone;
  *p++ = (EMUSHORT)0;
  *p++ = HIGHT_EXONE; /* 0x3fff... */
  for( i = 0; i < ne - 1; i++ ) *p++ = MASK_ALL_BITS;
#else
  /* hight part */
  p = exone + ne;
  *p-- = (EMUSHORT)0;
  *p-- = HIGHT_EXONE;
  for( i = 0; i < ne - 1; i++ ) *p-- = MASK_ALL_BITS;
#endif

  /* Copy Exponent */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( exp, &xi[1],    ne+1, ne );
#else
  ei_cpye_unpack( exp, &xi[ns+2], ne+1, ne );
#endif


  if( ei_cmp0e( exp, ne+1 ) == 0 )
  {
    /**********************************************
      A denormalized number.
      ----------------------
      Multiplyng by 2^N_MANT_BITS normalizes it;
      we then subtract the N_MANT_BITS we added
      to the Exponent.
     **********************************************/
    ei_cpye_unpack( pwr2, &n_mant_bits, ne+1, 1 );
    ei_ldexp( ti, pwr2, one, ne+1, nb );
    ei_mul( ti, xi, ti, nb );
    ei_logb( pwr2, ti, ne+1, nb ); /* Recursion */
    ei_cpye_unpack( inc, &n_mant_bits, ne+1, 1 );
    ei_sube( base2, pwr2, inc, ne+1 );
    ei_cvte_unpack( lpbase2, base2, nlp, ne+1 ); /* nlp >= ne+1 */

    /* FREE xi ****************/
    /* FREE zero **************/
    /* FREE one ***************/
    /* FREE ti ****************/
    __mpu_sbrk( -(int)(4*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE exp ***************/
    /* FREE base2 *************/
    /* FREE exone *************/
    /* FREE pwr2 **************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(5*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  ei_sube( base2, exp, exone, ne+1 );
  ei_cvte_unpack( lpbase2, base2, nlp, ne+1 ); /* nlp >= ne+1 */

  /* FREE xi ****************/
  /* FREE zero **************/
  /* FREE one ***************/
  /* FREE ti ****************/
  __mpu_sbrk( -(int)(4*np*SIZE_OF_EMUSHORT) );
  /**************************/

  /* FREE exp ***************/
  /* FREE base2 *************/
  /* FREE exone *************/
  /* FREE pwr2 **************/
  /* FREE inc ***************/
  __mpu_sbrk( -(int)(5*(ne+1)*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_logb() */


void ei_sqrt( EMUSHORT *eic, EMUSHORT *eia, int nb )
/***************************************************************

 Description        : ei_sqrt() Работает с
                                internal e-type data struct.

 Concepts           : Longhand SQUARE ROOT routine.
                      =========================================
                      Вычисление обыкновенного КВАДРАТНОГО
                      КОРНЯ. (Если аргумент отрицательный,
                      то результат равен нулю).

 Use Global Variable:

 Use Functions      :
                      internal_np( nb );          | this file
                      internal_ne( nb );          | this file
                      internal_ns( nb );          | this file

 Parameters         :
                      EMUSHORT *eic;    - указатель на
                                          internal e-type
                                          data struct.
                                          TARGET;
                      EMUSHORT *eia;    - указатель на
                                          internal e-type
                                          data struct.
                                          SOURCE;
                      int nb;           - количество бит в
                                          external e-type
                                          data struct;
                                          EIA, & EIC.

 Return             : [void]

 ***************************************************************/
{
  EMUSHORT           *exp = NULL,
                     *inc = NULL,
                      *mt = NULL,
                       *m = NULL,
                *sqrndbit = NULL,
                    *temp = NULL,
                     *num = NULL,
                      *sq = NULL,
                      *xi = NULL,
                      *xa = NULL, /* temp EIA for _mtherr() */
                    *zero = NULL;
  EMUSHORT      *p;
  __mpu_int32_t  j;
  int            np, ne, ns, i, w;
  int            k, l, n, nlups;

  if( nb < NBR_32 )
  {
    /* error: Invalid size of operand(s) */
    __real_error_no = __R_ESIZE__;
    __STIND; /* Set REAL ind-produsing operation Flag */
    return;
  }

  np = internal_np( nb );
  ne = internal_ne( nb );
  ns = internal_ns( nb );

  /*** Allocate memory for sqrndbit . *************************/
  sqrndbit = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !sqrndbit )
  {
    /* fatal error */
    return;
  }
  /************************************************************/

  ei_cleaz( sqrndbit, nb );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  sqrndbit[ne+ns+1] = (EMUSHORT)1; /* low part of Significand */
#else
  sqrndbit[1]       = (EMUSHORT)1; /* low part of Significand */
#endif

  /*** Allocate memory for xa . *******************************/
  xa = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !xa )
  {
    /* fatal error */

    /* FREE sqrndbit **********/
    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  ei_copy( xa, eia, nb );

  /*** Allocate memory for zero . *****************************/
  zero = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !zero )
  {
    /* fatal error */

    /* FREE sqrndbit **********/
    /* FREE xa ****************/
    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  /* Check for EIA <= 0 */
  _gen_zero( zero, nb );
  l = ei_cmp( eia, zero, nb );
  if( l <= 0 )
  {
    if( l == -2 )
    {
      ei_nan( eic, ei_isneg( eia, nb ), nb );

      /* FREE sqrndbit **********/
      /* FREE xa ****************/
      /* FREE zero **************/
      __mpu_sbrk( -(int)(3*np*SIZE_OF_EMUSHORT) );
      /**************************/

      return;
    }

    ei_cleaz( eic, nb );

    if( l < 0 )
    {
      /* "argument domain error" */
      /***************************************************
        NOTE:
          Функция _mtherr() является переходником между
          внутренним форматом и внешней,
          переопределяемой пользователем, функцией
          __mpu_math_error(). Кроме основных действий
          она выставляет системную переменную errno
          следующим образом.

            errno = __mpu_math_errnotab[type];
       ***************************************************/
      _mtherr( eic, (__mpu_char8_t *)"sqrt", __DOMAIN__,
               eic, xa, (EMUSHORT *)0, nb );
      __STDOM; /* Set REAL Domain Flag */
    }

    /* FREE sqrndbit **********/
    /* FREE xa ****************/
    /* FREE zero **************/
    __mpu_sbrk( -(int)(3*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;

  } /* End if( l <= 0 ) */

  /* Check Infinity */
  if( ei_isinfin( eia, nb ) )
  {
    ei_infin( eic, ei_isneg( eia, nb ), nb );

    /* FREE sqrndbit **********/
    /* FREE xa ****************/
    /* FREE zero **************/
    __mpu_sbrk( -(int)(3*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }


  /*** Allocate memory for temp, num, sq, xi . ****************/
  temp = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !temp )
  {
    /* fatal error */

    /* FREE sqrndbit **********/
    /* FREE xa ****************/
    /* FREE zero **************/
    __mpu_sbrk( -(int)(3*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  num = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !num )
  {
    /* fatal error */

    /* FREE sqrndbit **********/
    /* FREE xa ****************/
    /* FREE zero **************/
    /* FREE temp **************/
    __mpu_sbrk( -(int)(4*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  sq = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !sq )
  {
    /* fatal error */

    /* FREE sqrndbit **********/
    /* FREE xa ****************/
    /* FREE zero **************/
    /* FREE temp **************/
    /* FREE num ***************/
    __mpu_sbrk( -(int)(5*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  xi = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
  if( !xi )
  {
    /* fatal error */

    /* FREE sqrndbit **********/
    /* FREE xa ****************/
    /* FREE zero **************/
    /* FREE temp **************/
    /* FREE num ***************/
    /* FREE sq ****************/
    __mpu_sbrk( -(int)(6*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/

  /*** Allocate memory for exp . ******************************/
  exp = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !exp )
  {
    /* fatal error */

    /* FREE sqrndbit **********/
    /* FREE xa ****************/
    /* FREE zero **************/
    /* FREE temp **************/
    /* FREE num ***************/
    /* FREE sq ****************/
    /* FREE xi ****************/
    __mpu_sbrk( -(int)(7*np*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  inc = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !inc )
  {
    /* fatal error */

    /* FREE sqrndbit **********/
    /* FREE xa ****************/
    /* FREE zero **************/
    /* FREE temp **************/
    /* FREE num ***************/
    /* FREE sq ****************/
    /* FREE xi ****************/
    __mpu_sbrk( -(int)(7*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE exp ***************/
    __mpu_sbrk( -(int)((ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  mt = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !mt )
  {
    /* fatal error */

    /* FREE sqrndbit **********/
    /* FREE xa ****************/
    /* FREE zero **************/
    /* FREE temp **************/
    /* FREE num ***************/
    /* FREE sq ****************/
    /* FREE xi ****************/
    __mpu_sbrk( -(int)(7*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE exp ***************/
    /* FREE inc ***************/
    __mpu_sbrk( -(int)(2*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }

  m = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
  if( !m )
  {
    /* fatal error */

    /* FREE sqrndbit **********/
    /* FREE xa ****************/
    /* FREE zero **************/
    /* FREE temp **************/
    /* FREE num ***************/
    /* FREE sq ****************/
    /* FREE xi ****************/
    __mpu_sbrk( -(int)(7*np*SIZE_OF_EMUSHORT) );
    /**************************/

    /* FREE exp ***************/
    /* FREE inc ***************/
    /* FREE mt ****************/
    __mpu_sbrk( -(int)(3*(ne+1)*SIZE_OF_EMUSHORT) );
    /**************************/

    return;
  }
  /************************************************************/


  /* Bring in the arg and renormalize if it is denormal. */
  ei_copy( xi, eia, nb );

  /* Copy Exponents */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  ei_cpye_unpack( m, &xi[1],    ne+1, ne );
#else
  ei_cpye_unpack( m, &xi[ns+2], ne+1, ne );
#endif
  if( ei_cmp0e( m, ne+1 ) == 0 )
  {
    /* m -= ei_normalize( xi ) */
    j = ei_normalize( xi, nb );
    ei_cvte_unpack( inc, (EMUSHORT *)&j, ne+1, 1 );
    ei_sube( m, m, inc, ne+1 );
  }

  /* bzero inc !!! */
  for( i = 0; i < ne+1; i++ ) inc[i] = (EMUSHORT)0;

  /**************************************
    Divide Exponent by 2.
   **************************************/
  /* Формирование HALF (экспоненты 0.5) */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p = &inc[0];    /* hight part of Exponent */
  *p++ = HIGHT_EXONE;
  for( i = 1; i < ne; i++ ) *p++ = MASK_ALL_BITS;
  --p;
  *p ^= 1; /* Low part of Exponent */
#else
  p = &inc[ne-1]; /* hight part of Exponent */
  *p-- = HIGHT_EXONE;
  for( i = 1; i < ne; i++ ) *p-- = MASK_ALL_BITS;
  ++p;
  *p ^= 1; /* Low part of Exponent */
#endif

  /* m -= 0x3f...fe; */
  ei_sube( m, m, inc, ne+1 );
  /* exp = (m / 2) + 0x3f...fe; */
  if( ei_cmp0e( m, ne+1 ) < 0 )
  {
    /* НЕЛЬЗЯ ПРОСТО СДВИНУТЬ ОТРИЦАТЕЛЬНОЕ ЧИСЛО. */
    ei_nege(  mt,  m, ne+1 );
    ei_shrn(  mt, mt, (unsigned)1, ne+1 );
    ei_nege( exp, mt, ne+1 );
  }
  else
    ei_shrn( exp, m, (unsigned)1, ne+1 );
  ei_adde( exp, exp, inc, ne+1 );

  /*** End Divide Exponent by 2 *********/

  /* Adjust if Exponent odd. */
  for( i = 0; i < ne+1; i++ ) inc[i] = (EMUSHORT)0;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  inc[ne] = (EMUSHORT)1; /* low part of Exponent */
#else
  inc[0]  = (EMUSHORT)1; /* low part of Exponent */
#endif

  /* mt = m & 1 */
  for( i = 0; i < ne+1; i++ ) mt[i] = m[i] & inc[i];

  if( ei_cmp0e( mt, ne+1 ) != 0 )
  {
    if( ei_cmp0e( m, ne+1 ) > 0 )
      ei_adde( exp, exp, inc, ne+1 ); /* exp += 1 */
    ei_shdown( xi, (unsigned)1, nb );
  }

  ei_cleaz(  sq, nb );
  ei_cleaz( num, nb );

  n     = ((BITS_PER_EMUSHORT)/2);
  nlups = EINSBITS(nb);   /* Количество бит мантиссы. */
  w     = 0;

#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p = &xi[ne+2]; /* hight part of Significand */
#else
  p = &xi[ns];   /* hight part of Significand */
#endif

  while( nlups > 0 )
  {
    /* Bring in next word of arg. */
    if( w < ns+1 ) /* Significand + lgw */
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
      num[ne+ns+2] = /* lgw */
#else
      num[0] =       /* lgw */
#endif
      *p;

    /* Do additional bit on last outer loop, for roundoff. */
    if( nlups <= ((BITS_PER_EMUSHORT)/2) ) n = nlups + 1;

    for( k = 0; k < n; k++ )
    {
      /* Next 2 bits of arg */
      ei_shup( num, (unsigned)2, nb );
      /* Shift up answer */
      ei_shup(  sq, (unsigned)1, nb );
      /* Make trial divisor */
      for( i = 0; i < np; i++ ) temp[i] = sq[i];
      ei_shup( temp, (unsigned)1, nb );
      ei_addm( temp, temp, sqrndbit, nb );
      /* Substract and insert answer bit if it goes in */
      if( ei_cmpm( temp, num, nb ) <= 0 )
      {
        ei_subm( num, num, temp, nb );
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
        sq[ne+ns+1] |= 1; /* low part of Significand */
#else
        sq[1]       |= 1; /* low part of Significand */
#endif
      } /* End if( ei_cmpm( temp, num ) <= 0 ) */

    } /* End for( k = 0; i < n; k++ ) */

    nlups -= n;
    w     += 1;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
    ++p; /* toward lgw */
#else
    --p; /* toward lgw */
#endif
  } /* End while( nlups > 0 ) */


  /* Adjust for extra, roundoff loop done. */
  /* exp += (EINSBITS(nb) - 1) - rndprc;   */
  /* т.к. в нашем случае (EINSBITS(nb) == rndprc)
     делаем exp += -1; т.е. округляем до количества
     бит в мантиссе во внутреннем формате. */
  ei_dece( exp, exp, ne+1 );

  /* Sticky bit = 1 if the remainder is nonzero. */
  k = 0;
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
  p = &num[ne+2]; /* hight part of Significand */
#else
  p = &num[ns];   /* hight part of Significand */
#endif
  for( i = 0; i < ns+1; i++ ) /* Significand + lgw */
  {
/* NOTE: x86_64: sizeof( long ) == 8!
 */
    k |= (int)(__mpu_uint64_t)
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
             p++; /* toward lgw */
#else
             p--; /* toward lgw */
#endif
  }

  /* Renormalize and round off. */
  ei_mdenorm( sq, k, 0, exp, 0, nb );

  ei_copy( eic, sq, nb );

  /* FREE sqrndbit **********/
  /* FREE xa ****************/
  /* FREE zero **************/
  /* FREE temp **************/
  /* FREE num ***************/
  /* FREE sq ****************/
  /* FREE xi ****************/
  __mpu_sbrk( -(int)(7*np*SIZE_OF_EMUSHORT) );
  /**************************/

  /* FREE exp ***************/
  /* FREE inc ***************/
  /* FREE mt ****************/
  /* FREE m *****************/
  __mpu_sbrk( -(int)(4*(ne+1)*SIZE_OF_EMUSHORT) );
  /**************************/

} /* End of ei_sqrt() */


/***************************************************************
  Hide internal symbols:
 ***************************************************************/

__mpu_hidden_decl(internal_ne);
__mpu_hidden_decl(internal_ns);
__mpu_hidden_decl(internal_np);

__mpu_hidden_decl(ei_cleaz);
__mpu_hidden_decl(ei_cleazs);

__mpu_hidden_decl(ei_ind);
__mpu_hidden_decl(ei_isind);
__mpu_hidden_decl(e_ind);
__mpu_hidden_decl(e_isind);

__mpu_hidden_decl(ei_nan);
__mpu_hidden_decl(ei_isnans);
__mpu_hidden_decl(e_nan);
__mpu_hidden_decl(e_isnans);

__mpu_hidden_decl(ei_nanmax);
__mpu_hidden_decl(ei_isnanmax);

__mpu_hidden_decl(e_nanmax);
__mpu_hidden_decl(e_isnanmax);

__mpu_hidden_decl(ei_nanmin);
__mpu_hidden_decl(ei_isnanmin);

__mpu_hidden_decl(e_nanmin);
__mpu_hidden_decl(e_isnanmin);

__mpu_hidden_decl(ei_infin);
__mpu_hidden_decl(ei_isinfin);

__mpu_hidden_decl(e_infin);
__mpu_hidden_decl(e_isinfin);

__mpu_hidden_decl(e_realmin);
__mpu_hidden_decl(e_realmax);

__mpu_hidden_decl(ei_signull);
__mpu_hidden_decl(ei_issignull);

__mpu_hidden_decl(e_signull);
__mpu_hidden_decl(e_issignull);

__mpu_hidden_decl(ei_neg);
__mpu_hidden_decl(ei_isneg);

__mpu_hidden_decl(e_neg);
__mpu_hidden_decl(e_isneg);

__mpu_hidden_decl(ei_abs);
__mpu_hidden_decl(e_abs);


/********************************************
  Functions for LONG INTEGER NUMBERS:
 */
__mpu_hidden_decl(ei_cmpe);
__mpu_hidden_decl(ei_cmp0e);
__mpu_hidden_decl(ei_cpye_pack);
__mpu_hidden_decl(ei_cpye_unpack);
__mpu_hidden_decl(ei_cpye);
__mpu_hidden_decl(ei_cvte_unpack);
__mpu_hidden_decl(ei_cvte_pack);
__mpu_hidden_decl(ei_cvte);

__mpu_hidden_decl(ei_adde);
__mpu_hidden_decl(ei_ince);
__mpu_hidden_decl(ei_sube);
__mpu_hidden_decl(ei_dece);
__mpu_hidden_decl(ei_nege);
__mpu_hidden_decl(ei_ande);

__mpu_hidden_decl(ei_shrn);
__mpu_hidden_decl(ei_shln);
/*
  End of Functions for LONG INTEGER NUMBERS.
 ********************************************/


__mpu_hidden_decl(ei_shdown);
__mpu_hidden_decl(ei_shup);
__mpu_hidden_decl(ei_shift);

__mpu_hidden_decl(ei_normalize);
__mpu_hidden_decl(unpack);

__mpu_hidden_decl(ei_cmpm);
__mpu_hidden_decl(ei_addm);
__mpu_hidden_decl(ei_subm);
__mpu_hidden_decl(ei_divm);
__mpu_hidden_decl(ei_mulm);

__mpu_hidden_decl(ei_mdenorm);

__mpu_hidden_decl(pack);

__mpu_hidden_decl(ei_copy);
__mpu_hidden_decl(ei_copyzlgw);

__mpu_hidden_decl(ei_cmp);
__mpu_hidden_decl(ei_convert);

__mpu_hidden_decl(ei_add);
__mpu_hidden_decl(ei_sub);
__mpu_hidden_decl(ei_div);
__mpu_hidden_decl(ei_mul);

__mpu_hidden_decl(ei_ltor);
__mpu_hidden_decl(ei_ultor);
__mpu_hidden_decl(ei_rtoul_frac);
__mpu_hidden_decl(ei_rtol_frac);

/***************************************************************
  GENERATORS OF CONSTANT:
 */
__mpu_hidden_decl(_gen_zero);
__mpu_hidden_decl(_gen_half);
__mpu_hidden_decl(_gen_one);
__mpu_hidden_decl(_gen_two);
__mpu_hidden_decl(_gen_ten);
__mpu_hidden_decl(_gen_mten);
__mpu_hidden_decl(_gen_32);
/*
  END GENERATORS OF CONSTANT.
 ***************************************************************/

__mpu_hidden_decl(ei_remain);
__mpu_hidden_decl(ei_floor);
__mpu_hidden_decl(ei_ceil);
__mpu_hidden_decl(ei_round);
__mpu_hidden_decl(ei_frexp);
__mpu_hidden_decl(ei_ldexp);
__mpu_hidden_decl(ei_logb);
__mpu_hidden_decl(ei_sqrt);


/*
  End of hide internal symbols.
 ***************************************************************/