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
author: kx <kx@radix-linux.su> 2024-12-20 16:11:07 +0300 committer: kx <kx@radix-linux.su> 2024-12-20 16:11:07 +0300 commit: 868b2b66b564b5c00e3a74d10be45db7151627ac parent: cce2ae8d3312493b7653358bb4af201d3271377b
Commit Summary:
Version 1.0.14
Diffstat:
1 file changed, 1940 insertions, 0 deletions
diff --git a/mpu/mpu-ioreal.c b/mpu/mpu-ioreal.c
new file mode 100644
index 0000000..e85e2ab
--- /dev/null
+++ b/mpu/mpu-ioreal.c
@@ -0,0 +1,2297 @@
+
+/***************************************************************
+  __MPU_IOREAL.C
+
+       This file contains source code of functions for
+       REAL input/output 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-floatp.h>
+#include <mpu-ioreal.h>
+
+#include <mpu-char.h>
+#include <mpu-symbols.h>
+
+#include <mpu-math-errno.h>
+#include <mpu-mtherr.h>
+
+
+#define NTEN_128      28
+#define NTEN_256      28
+
+#define NTEN_512      60
+#define NTEN_1024     60
+
+#define NTEN_2048    124
+#define NTEN_4096    124
+
+#define NTEN_8192    252
+#define NTEN_16384   252
+
+#define NTEN_32768   508
+#define NTEN_65536   508
+
+#define NTEN_131072 1020
+
+
+static int _get_nten( int nb )
+{
+  int  rc = 0;
+
+  if( nb < NBR_32 || nb > MPU_REAL_IO_LIMIT )
+  {
+    /* error: Invalid size of operand(s) */
+    __real_error_no = __R_ESIZE__;
+    __STIND; /* Set REAL ind-produsing operation Flag */
+    return( rc );
+  }
+
+  switch( nb )
+  {
+    case NBR_32   :
+    case NBR_64   :
+    case NBR_128  :
+       rc = NTEN_128;
+       break;
+    case NBR_256  :
+       rc = NTEN_256;
+       break;
+    case NBR_512  :
+       rc = NTEN_512;
+       break;
+    case NBR_1024 :
+       rc = NTEN_1024;
+       break;
+    case NBR_2048 :
+       rc = NTEN_2048;
+       break;
+    case NBR_4096 :
+       rc = NTEN_4096;
+       break;
+    case NBR_8192 :
+       rc = NTEN_8192;
+       break;
+    case NBR_16384:
+       rc = NTEN_16384;
+       break;
+    case NBR_32768:
+       rc = NTEN_32768;
+       break;
+    case NBR_65536:
+       rc = NTEN_65536;
+       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 _get_nten() */
+
+
+/***************************************************************
+  Кодировка имен файлов:
+
+  Трехзначное десятичное число, представляющее количество
+  128-и битных слов, из которых состоят вещественные числа
+  размещенные в массивах:
+
+    размер чисел в битах  кодировка
+    --------------------  ---------
+                     128  001
+                     256  002
+                     512  004
+                    1024  008
+                    2048  016
+                    4096  032
+                    8192  064
+                   16384  128
+                   32768  256
+                   65536  512 (это предел);
+
+    ПРИМЕРЫ:
+    -------
+      ei_mtens_001_emu32lsb.dfn -   128-бит,
+      ei_mtens_512_emu32lsb.dfn - 65536-бит.
+
+ ***************************************************************/
+
+#if MPU_REAL_IO_LIMIT >= 128
+#if MPU_WORD_ORDER_BIG_ENDIAN == 0
+#include <etens/emu00128/ei_mtens_001_emu32lsb.dfn>
+#include <etens/emu00128/ei_ptens_001_emu32lsb.dfn>
+#else
+#include <etens/emu00128/ei_mtens_001_emu32msb.dfn>
+#include <etens/emu00128/ei_ptens_001_emu32msb.dfn>
+#endif
+#endif /* MPU_REAL_IO_LIMIT >= 128 */
+
+#if MPU_REAL_IO_LIMIT >= 256
+#if MPU_WORD_ORDER_BIG_ENDIAN == 0
+#include <etens/emu00256/ei_mtens_002_emu32lsb.dfn>
+#include <etens/emu00256/ei_ptens_002_emu32lsb.dfn>
+#else
+#include <etens/emu00256/ei_mtens_002_emu32msb.dfn>
+#include <etens/emu00256/ei_ptens_002_emu32msb.dfn>
+#endif
+#endif /* MPU_REAL_IO_LIMIT >= 256 */
+
+#if MPU_REAL_IO_LIMIT >= 512
+#if MPU_WORD_ORDER_BIG_ENDIAN == 0
+#include <etens/emu00512/ei_mtens_004_emu32lsb.dfn>
+#include <etens/emu00512/ei_ptens_004_emu32lsb.dfn>
+#else
+#include <etens/emu00512/ei_mtens_004_emu32msb.dfn>
+#include <etens/emu00512/ei_ptens_004_emu32msb.dfn>
+#endif
+#endif /* MPU_REAL_IO_LIMIT >= 512 */
+
+#if MPU_REAL_IO_LIMIT >= 1024
+#if MPU_WORD_ORDER_BIG_ENDIAN == 0
+#include <etens/emu01024/ei_mtens_008_emu32lsb.dfn>
+#include <etens/emu01024/ei_ptens_008_emu32lsb.dfn>
+#else
+#include <etens/emu01024/ei_mtens_008_emu32msb.dfn>
+#include <etens/emu01024/ei_ptens_008_emu32msb.dfn>
+#endif
+#endif /* MPU_REAL_IO_LIMIT >= 1024 */
+
+#if MPU_REAL_IO_LIMIT >= 2048
+#if MPU_WORD_ORDER_BIG_ENDIAN == 0
+#include <etens/emu02048/ei_mtens_016_emu32lsb.dfn>
+#include <etens/emu02048/ei_ptens_016_emu32lsb.dfn>
+#else
+#include <etens/emu02048/ei_mtens_016_emu32msb.dfn>
+#include <etens/emu02048/ei_ptens_016_emu32msb.dfn>
+#endif
+#endif /* MPU_REAL_IO_LIMIT >= 2048 */
+
+#if MPU_REAL_IO_LIMIT >= 4096
+#if MPU_WORD_ORDER_BIG_ENDIAN == 0
+#include <etens/emu04096/ei_mtens_032_emu32lsb.dfn>
+#include <etens/emu04096/ei_ptens_032_emu32lsb.dfn>
+#else
+#include <etens/emu04096/ei_mtens_032_emu32msb.dfn>
+#include <etens/emu04096/ei_ptens_032_emu32msb.dfn>
+#endif
+#endif /* MPU_REAL_IO_LIMIT >= 4096 */
+
+#if MPU_REAL_IO_LIMIT >= 8192
+#if MPU_WORD_ORDER_BIG_ENDIAN == 0
+#include <etens/emu08192/ei_mtens_064_emu32lsb.dfn>
+#include <etens/emu08192/ei_ptens_064_emu32lsb.dfn>
+#else
+#include <etens/emu08192/ei_mtens_064_emu32msb.dfn>
+#include <etens/emu08192/ei_ptens_064_emu32msb.dfn>
+#endif
+#endif /* MPU_REAL_IO_LIMIT >= 8192 */
+
+#if MPU_REAL_IO_LIMIT >= 16384
+#if MPU_WORD_ORDER_BIG_ENDIAN == 0
+#include <etens/emu16384/ei_mtens_128_emu32lsb.dfn>
+#include <etens/emu16384/ei_ptens_128_emu32lsb.dfn>
+#else
+#include <etens/emu16384/ei_mtens_128_emu32msb.dfn>
+#include <etens/emu16384/ei_ptens_128_emu32msb.dfn>
+#endif
+#endif /* MPU_REAL_IO_LIMIT >= 16384 */
+
+#if MPU_REAL_IO_LIMIT >= 32768
+#if MPU_WORD_ORDER_BIG_ENDIAN == 0
+#include <etens/emu32768/ei_mtens_256_emu32lsb.dfn>
+#include <etens/emu32768/ei_ptens_256_emu32lsb.dfn>
+#else
+#include <etens/emu32768/ei_mtens_256_emu32msb.dfn>
+#include <etens/emu32768/ei_ptens_256_emu32msb.dfn>
+#endif
+#endif /* MPU_REAL_IO_LIMIT >= 32768 */
+
+#if MPU_REAL_IO_LIMIT >= 65536
+#if MPU_WORD_ORDER_BIG_ENDIAN == 0
+#include <etens/emu65536/ei_mtens_512_emu32lsb.dfn>
+#include <etens/emu65536/ei_ptens_512_emu32lsb.dfn>
+#else
+#include <etens/emu65536/ei_mtens_512_emu32msb.dfn>
+#include <etens/emu65536/ei_ptens_512_emu32msb.dfn>
+#endif
+#endif /* MPU_REAL_IO_LIMIT >= 65536 */
+
+
+static EMUSHORT *_get_tens_ptr( int nb )
+{
+  EMUSHORT *rc = (EMUSHORT *)NULL;
+
+  if( nb < NBR_32 || nb > MPU_REAL_IO_LIMIT )
+  {
+    /* error: Invalid size of operand(s) */
+    __real_error_no = __R_ESIZE__;
+    __STIND; /* Set REAL ind-produsing operation Flag */
+    return( rc );
+  }
+
+  switch( nb )
+  {
+#if MPU_REAL_IO_LIMIT >= 128
+    case NBR_32   :
+    case NBR_64   :
+    case NBR_128  :
+      rc =   (EMUSHORT *)&_ei_tens_128_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 128 */
+#if MPU_REAL_IO_LIMIT >= 256
+    case NBR_256  :
+      rc =   (EMUSHORT *)&_ei_tens_256_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 256 */
+#if MPU_REAL_IO_LIMIT >= 512
+    case NBR_512  :
+      rc =   (EMUSHORT *)&_ei_tens_512_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 512 */
+#if MPU_REAL_IO_LIMIT >= 1024
+    case NBR_1024 :
+      rc =  (EMUSHORT *)&_ei_tens_1024_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 1024 */
+#if MPU_REAL_IO_LIMIT >= 2048
+    case NBR_2048 :
+      rc =  (EMUSHORT *)&_ei_tens_2048_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 2048 */
+#if MPU_REAL_IO_LIMIT >= 4096
+    case NBR_4096 :
+      rc =  (EMUSHORT *)&_ei_tens_4096_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 4096 */
+#if MPU_REAL_IO_LIMIT >= 8192
+    case NBR_8192 :
+      rc =  (EMUSHORT *)&_ei_tens_8192_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 8192 */
+#if MPU_REAL_IO_LIMIT >= 16384
+    case NBR_16384:
+      rc = (EMUSHORT *)&_ei_tens_16384_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 16384 */
+#if MPU_REAL_IO_LIMIT >= 32768
+    case NBR_32768:
+      rc = (EMUSHORT *)&_ei_tens_32768_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 32768 */
+#if MPU_REAL_IO_LIMIT >= 65536
+    case NBR_65536:
+      rc = (EMUSHORT *)&_ei_tens_65536_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 65536 */
+
+    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 _get_tens_ptr() */
+
+
+static EMUSHORT *_get_mtens_ptr( int nb )
+{
+  EMUSHORT *rc = (EMUSHORT *)NULL;
+
+  if( nb < NBR_32 || nb > MPU_REAL_IO_LIMIT )
+  {
+    /* error: Invalid size of operand(s) */
+    __real_error_no = __R_ESIZE__;
+    __STIND; /* Set REAL ind-produsing operation Flag */
+    return( rc );
+  }
+
+  switch( nb )
+  {
+#if MPU_REAL_IO_LIMIT >= 128
+    case NBR_32   :
+    case NBR_64   :
+    case NBR_128  :
+      rc =   (EMUSHORT *)&_ei_mtens_128_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 128 */
+#if MPU_REAL_IO_LIMIT >= 256
+    case NBR_256  :
+      rc =   (EMUSHORT *)&_ei_mtens_256_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 256 */
+#if MPU_REAL_IO_LIMIT >= 512
+    case NBR_512  :
+      rc =   (EMUSHORT *)&_ei_mtens_512_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 512 */
+#if MPU_REAL_IO_LIMIT >= 1024
+    case NBR_1024 :
+      rc =  (EMUSHORT *)&_ei_mtens_1024_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 1024 */
+#if MPU_REAL_IO_LIMIT >= 2048
+    case NBR_2048 :
+      rc =  (EMUSHORT *)&_ei_mtens_2048_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 2048 */
+#if MPU_REAL_IO_LIMIT >= 4096
+    case NBR_4096 :
+      rc =  (EMUSHORT *)&_ei_mtens_4096_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 4096 */
+#if MPU_REAL_IO_LIMIT >= 8192
+    case NBR_8192 :
+      rc =  (EMUSHORT *)&_ei_mtens_8192_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 8192 */
+#if MPU_REAL_IO_LIMIT >= 16384
+    case NBR_16384:
+      rc = (EMUSHORT *)&_ei_mtens_16384_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 16384 */
+#if MPU_REAL_IO_LIMIT >= 32768
+    case NBR_32768:
+      rc = (EMUSHORT *)&_ei_mtens_32768_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 32768 */
+#if MPU_REAL_IO_LIMIT >= 65536
+    case NBR_65536:
+      rc = (EMUSHORT *)&_ei_mtens_65536_[0][0];
+      break;
+#endif /* MPU_REAL_IO_LIMIT >= 65536 */
+
+    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 _get_mtens_ptr() */
+
+
+/***************************************************************
+  SEE: __MPU_FLOATP.H for definitions REAL_xxxxxx__MAX_STRING
+ ***************************************************************/
+
+#define MAX_STRING_SIZE(n)   REAL_##n##_MAX_STRING
+
+#if MPU_REAL_IO_LIMIT == 32
+#define REAL_MAX_STRING_SIZE    MAX_STRING_SIZE(32)
+#else
+#if MPU_REAL_IO_LIMIT == 64
+#define REAL_MAX_STRING_SIZE    MAX_STRING_SIZE(64)
+#else
+#if MPU_REAL_IO_LIMIT == 128
+#define REAL_MAX_STRING_SIZE    MAX_STRING_SIZE(128)
+#else
+#if MPU_REAL_IO_LIMIT == 256
+#define REAL_MAX_STRING_SIZE    MAX_STRING_SIZE(256)
+#else
+#if MPU_REAL_IO_LIMIT == 512
+#define REAL_MAX_STRING_SIZE    MAX_STRING_SIZE(512)
+#else
+#if MPU_REAL_IO_LIMIT == 1024
+#define REAL_MAX_STRING_SIZE    MAX_STRING_SIZE(1024)
+#else
+#if MPU_REAL_IO_LIMIT == 2048
+#define REAL_MAX_STRING_SIZE    MAX_STRING_SIZE(2048)
+#else
+#if MPU_REAL_IO_LIMIT == 4096
+#define REAL_MAX_STRING_SIZE    MAX_STRING_SIZE(4096)
+#else
+#if MPU_REAL_IO_LIMIT == 8192
+#define REAL_MAX_STRING_SIZE    MAX_STRING_SIZE(8192)
+#else
+#if MPU_REAL_IO_LIMIT == 16384
+#define REAL_MAX_STRING_SIZE    MAX_STRING_SIZE(16384)
+#else
+#if MPU_REAL_IO_LIMIT == 32768
+#define REAL_MAX_STRING_SIZE    MAX_STRING_SIZE(32768)
+#else
+#if MPU_REAL_IO_LIMIT == 65536
+#define REAL_MAX_STRING_SIZE    MAX_STRING_SIZE(65536)
+#else
+#if MPU_REAL_IO_LIMIT == 131072
+#define REAL_MAX_STRING_SIZE    MAX_STRING_SIZE(131072)
+#else
+#error mpu-ioreal.c: Failed value of MPU_REAL_IO_LIMIT (use: 32,64, ..., 131072)
+#endif /* MPU_REAL_IO_LIMIT == 131072 */
+#endif /* MPU_REAL_IO_LIMIT ==  65536 */
+#endif /* MPU_REAL_IO_LIMIT ==  32768 */
+#endif /* MPU_REAL_IO_LIMIT ==  16384 */
+#endif /* MPU_REAL_IO_LIMIT ==   8192 */
+#endif /* MPU_REAL_IO_LIMIT ==   4096 */
+#endif /* MPU_REAL_IO_LIMIT ==   2048 */
+#endif /* MPU_REAL_IO_LIMIT ==   1024 */
+#endif /* MPU_REAL_IO_LIMIT ==    512 */
+#endif /* MPU_REAL_IO_LIMIT ==    256 */
+#endif /* MPU_REAL_IO_LIMIT ==    128 */
+#endif /* MPU_REAL_IO_LIMIT ==     64 */
+#endif /* MPU_REAL_IO_LIMIT ==     32 */
+
+
+void ei_real_to_ascii( __mpu_char8_t *string, EMUSHORT *ei, int ndigs, int exp_delim, int exp_digs, int gen_plus, int nb )
+/***************************************************************
+
+ Description        : ei_real_to_ascii() Работает с
+                                         internal e-type
+                                         data struct.
+
+ Concepts           : Convert internal e-type EI to ASCII
+                      STRING with NDIGS digits after the
+                      decimal point.
+                      EXP_DELIM is char to delimited Exponent
+                      in the output STRING, for example,
+                      1.j+27.
+
+ Use Global Variable:
+
+ Use Functions      :
+                      iitoa_np();                 | mpu-integer.c
+                      internal_np( nb );          | mpu-real.c
+                      internal_ne( nb );          | mpu-real.c
+                      internal_ns( nb );          | mpu-real.c
+
+ Parameters         :
+                      __mpu_char8_t *string; - output string;
+                      EMUSHORT          *ei; - указатель на
+                                               internal e-type
+                                               data struct;
+                      int             ndigs; - количество цифр
+                                               после десятичной
+                                               точки;
+                      int         exp_delim; - символ отделяющий
+                                               ЭКСРОНЕНТУ;
+                      int          exp_digs; - количество цифр
+                                               экспоненты;
+                      NOTE ====================================
+                           В том случае, когда( exp_digs > 0 )
+                           {
+                             Если реальное количество цифр
+                             меньше exp_digs, то экспонента
+                             будет дополнена старшими
+                             незначащими нулями.
+                             Если реальное количество цифр
+                             больше exp_digs, то экспонента
+                             изменена не будет.
+                           }
+                      =========================================
+
+                      int          gen_plus; - принудительная
+                                               генерация знака
+                                               плюс перед
+                                               положтельным
+                                               числом;
+                      NOTE ====================================
+                           В случае, когда( gen_plus != 0 )
+                           {
+                             При переводе положительного
+                             числа в строку происходит
+                             принудительная запись знака 
+                             плюс перед числом в строке.
+                           }
+                           иначе
+                           {
+                             Положительное число печатается
+                             как обычно (т.е. без знака).
+                           }
+                      =========================================
+
+                      int                nb; - количество бит в
+                                               external e-type
+                                               data struct.
+
+ Return             : [void]
+
+ ***************************************************************/
+{
+  EMUSHORT          *n = NULL,
+                    *m = NULL,
+                *expon = NULL,
+                *exone = NULL,
+                  *inc = NULL,
+
+                *equot = NULL,
+                  *tmp = NULL,
+                  *ten = NULL,
+                    *y = NULL,
+                    *t = NULL,
+                    *u = NULL,
+                    *w = NULL;
+  EMUSHORT      *p, *r;
+  EMUSHORT       sign;
+  __mpu_int32_t  j, digit;
+  int            rndsave, n_ten;
+  int            jc, k;
+  __mpu_char8_t *s, *ss, *t_string = NULL;
+  int            np, ne, ns, i, ln, n_dec;
+
+
+  errno = 0;
+
+  if( nb < NBR_32 || nb > MPU_REAL_IO_LIMIT )
+  {
+    /* error: Invalid size of operand(s) */
+    __real_error_no = __R_ESIZE__;
+    __STIND; /* Set REAL ind-produsing operation Flag */
+    return;
+  }
+
+  t_string = (__mpu_char8_t *)malloc(REAL_MAX_STRING_SIZE+1);
+  if( !t_string )
+  {
+    /* fatal error */
+    return;
+  }
+
+  rndsave = rndprc;
+  ss  = string;
+  s   = t_string;
+  *ss = '\0';
+  ln = _get_max_string( nb );
+  for( i = 0; i < ln; i++ ) s[i] = '\0'; /* or bzero( s, ln ); */
+
+  np = internal_np( nb );
+  ne = internal_ne( nb );
+  ns = internal_ns( nb );
+
+
+  /*** Allocate memory for n, m, expon, exone, inc . **********/
+  n = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
+  if( !n )
+  {
+    /* fatal error */
+
+    /* FREE t_string **********/
+    free( t_string );
+    /**************************/
+
+    return;
+  }
+
+  m = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
+  if( !m )
+  {
+    /* fatal error */
+
+    /* FREE t_string **********/
+    free( t_string );
+    /**************************/
+
+    /* FREE n *****************/
+    __mpu_sbrk( -(int)((ne+1)*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    return;
+  }
+
+  expon = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
+  if( !expon )
+  {
+    /* fatal error */
+
+    /* FREE t_string **********/
+    free( t_string );
+    /**************************/
+
+    /* FREE n *****************/
+    /* FREE m *****************/
+    __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 t_string **********/
+    free( t_string );
+    /**************************/
+
+    /* FREE n *****************/
+    /* FREE m *****************/
+    /* FREE expon *************/
+    __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 t_string **********/
+    free( t_string );
+    /**************************/
+
+    /* FREE n *****************/
+    /* FREE m *****************/
+    /* FREE expon *************/
+    /* FREE exone *************/
+    __mpu_sbrk( -(int)(4*(ne+1)*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    return;
+  }
+  /************************************************************/
+
+  /*** Allocate memory for equot, tmp, ten, y, t, u, w . ******/
+  equot = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
+  if( !equot )
+  {
+    /* fatal error */
+
+    /* FREE t_string **********/
+    free( t_string );
+    /**************************/
+
+    /* FREE n *****************/
+    /* FREE m *****************/
+    /* FREE expon *************/
+    /* FREE exone *************/
+    /* FREE inc ***************/
+    __mpu_sbrk( -(int)(5*(ne+1)*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    return;
+  }
+
+  tmp = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
+  if( !tmp )
+  {
+    /* fatal error */
+
+    /* FREE t_string **********/
+    free( t_string );
+    /**************************/
+
+    /* FREE n *****************/
+    /* FREE m *****************/
+    /* FREE expon *************/
+    /* FREE exone *************/
+    /* FREE inc ***************/
+    __mpu_sbrk( -(int)(5*(ne+1)*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    /* FREE equot *************/
+    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    return;
+  }
+
+  ten = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
+  if( !ten )
+  {
+    /* fatal error */
+
+    /* FREE t_string **********/
+    free( t_string );
+    /**************************/
+
+    /* FREE n *****************/
+    /* FREE m *****************/
+    /* FREE expon *************/
+    /* FREE exone *************/
+    /* FREE inc ***************/
+    __mpu_sbrk( -(int)(5*(ne+1)*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    /* FREE equot *************/
+    /* FREE tmp ***************/
+    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    return;
+  }
+
+  y = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
+  if( !y )
+  {
+    /* fatal error */
+
+    /* FREE t_string **********/
+    free( t_string );
+    /**************************/
+
+    /* FREE n *****************/
+    /* FREE m *****************/
+    /* FREE expon *************/
+    /* FREE exone *************/
+    /* FREE inc ***************/
+    __mpu_sbrk( -(int)(5*(ne+1)*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    /* FREE equot *************/
+    /* FREE tmp ***************/
+    /* FREE ten ***************/
+    __mpu_sbrk( -(int)(3*np*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    return;
+  }
+
+  t = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
+  if( !t )
+  {
+    /* fatal error */
+
+    /* FREE t_string **********/
+    free( t_string );
+    /**************************/
+
+    /* FREE n *****************/
+    /* FREE m *****************/
+    /* FREE expon *************/
+    /* FREE exone *************/
+    /* FREE inc ***************/
+    __mpu_sbrk( -(int)(5*(ne+1)*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    /* FREE equot *************/
+    /* FREE tmp ***************/
+    /* FREE ten ***************/
+    /* FREE y *****************/
+    __mpu_sbrk( -(int)(4*np*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    return;
+  }
+
+  u = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
+  if( !u )
+  {
+    /* fatal error */
+
+    /* FREE t_string **********/
+    free( t_string );
+    /**************************/
+
+    /* FREE n *****************/
+    /* FREE m *****************/
+    /* FREE expon *************/
+    /* FREE exone *************/
+    /* FREE inc ***************/
+    __mpu_sbrk( -(int)(5*(ne+1)*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    /* FREE equot *************/
+    /* FREE tmp ***************/
+    /* FREE ten ***************/
+    /* FREE y *****************/
+    /* FREE t *****************/
+    __mpu_sbrk( -(int)(5*np*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    return;
+  }
+
+  w = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
+  if( !w )
+  {
+    /* fatal error */
+
+    /* FREE t_string **********/
+    free( t_string );
+    /**************************/
+
+    /* FREE n *****************/
+    /* FREE m *****************/
+    /* FREE expon *************/
+    /* FREE exone *************/
+    /* FREE inc ***************/
+    __mpu_sbrk( -(int)(5*(ne+1)*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    /* FREE equot *************/
+    /* FREE tmp ***************/
+    /* FREE ten ***************/
+    /* FREE y *****************/
+    /* FREE t *****************/
+    /* FREE u *****************/
+    __mpu_sbrk( -(int)(6*np*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    return;
+  }
+  /************************************************************/
+
+
+
+  n_dec = _get_ndec( nb );
+  n_ten = _get_nten( nb );
+
+  if( nb > NBR_64 )
+    n_dec -= 1; /* Необходимо для правильного округления мантиссы */
+
+  if( ei_isind( ei, nb ) )
+  {
+    strncpy( t_string, " -ind", 6 ); /* " -1.#IND00"; */
+
+    if( exp_delim == 'r' || exp_delim == 'R' )
+    {
+      strcat( t_string, "_r" );
+    }
+    else if( exp_delim == 'j' || exp_delim == 'J' )
+    {
+      strcat( t_string, "_j" );
+    }
+    goto bxit;
+  }
+
+  if( ei_isnans( ei, nb ) )
+  {
+    if( ei_isneg( ei, nb ) ) strncpy( t_string, " -", 3 );
+    else if( gen_plus )      strncpy( t_string, " +", 3 );
+         else                strncpy( t_string, " ",  2 ); /* + */
+    strcat( t_string, "NaN" ); /* "1.#QNAN0"; */
+
+    if( exp_delim == 'r' || exp_delim == 'R' )
+    {
+      strcat( t_string, "_r" );
+    }
+    else if( exp_delim == 'j' || exp_delim == 'J' )
+    {
+      strcat( t_string, "_j" );
+    }
+    goto bxit;
+  }
+
+  rndprc = (int)NSBITS(nb); /* Set to full precision */
+  ei_copy( y, ei, nb );
+
+  /* Save Sign */
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+  if( y[0] )
+#else
+  if( y[ns + ne + 2] )
+#endif
+  {
+    sign = MASK_ALL_BITS;
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+    y[0]           = (EMUSHORT)0; /* Clear sign */
+#else
+    y[ns + ne + 2] = (EMUSHORT)0; /* Clear sign */
+#endif
+  }
+  else
+  {
+    sign =  (EMUSHORT)0;
+  }
+
+  /* expon = 0 */
+  for( i = 0; i < ne+1; i++ ) expon[i] = (EMUSHORT)0;
+
+  /* ten = 1.0E1 */
+  _gen_ten( ten, nb );
+
+  /* t = 1.0E0 */
+  _gen_one( t, nb );
+
+  /* Gen 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
+
+
+  /**************************
+    Test for zero Exponent
+   **************************/
+  /* Copy Exponents */
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+  ei_cpye_unpack( inc, &y[1],    ne+1, ne );
+#else
+  ei_cpye_unpack( inc, &y[ns+2], ne+1, ne );
+#endif
+  if( ei_cmp0e( inc, ne+1 ) == 0 ) /* Exponent == 0 */
+  {
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+    for( i = ne+2; i < np-1; i++ )
+#else
+    for( i = 1; i < ns+1; i++ )
+#endif
+    {
+      if( y[i] != (EMUSHORT)0 )
+        goto tnzero; /* Denormalized number */
+    }
+    goto isone;        /* Valid all zeros */
+  } /* End if( Exponent == 0 ) */
+
+tnzero:
+
+  /*********************
+    Test for infinity
+   *********************/
+  if( ei_isinfin( y, nb ) )
+  {
+    if( sign )          strncpy( t_string, " -inf", 6 ); /* " -1.#INF00"; */
+    else if( gen_plus ) strncpy( t_string, " +inf", 6 ); /* " +1.#INF00"; */
+         else           strncpy( t_string, " inf",  5 );  /* " 1.#INF00"; */
+
+    if( exp_delim == 'r' || exp_delim == 'R' )
+    {
+      strcat( t_string, "_r" );
+    }
+    else if( exp_delim == 'j' || exp_delim == 'J' )
+    {
+      strcat( t_string, "_j" );
+    }
+    goto bxit;
+
+  } /* End of Infin */
+
+  /**********************************************************
+    Test for Exponent nonzero but Significand denormalized.
+    This is an ERROR condition.
+   **********************************************************/
+  if( (ei_cmp0e( inc, ne+1 ) != 0) &&
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+     ((y[ne+2] & MASK_SIGN) == 0) )
+#else
+     ((y[ns]   & MASK_SIGN) == 0) )
+#endif
+  {
+    /* "domain error" */
+    errno = __mpu_math_errnotab[__DOMAIN__];
+    __STDOM; /* Set REAL Domain Flag */
+    strncpy( t_string, "NaN", 4 ); /* "1.#QNAN0"; */
+
+    if( exp_delim == 'r' || exp_delim == 'R' )
+    {
+      strcat( t_string, "_r" );
+    }
+    else if( exp_delim == 'j' || exp_delim == 'J' )
+    {
+      strcat( t_string, "_j" );
+    }
+    goto bxit;
+  }
+
+  /******************
+    Compare to 1.0
+   ******************/
+  jc = ei_cmp( t, y, nb );
+  if( jc == 0 ) goto isone;
+
+  if( jc == -2 )
+  {
+    /* abort() */
+    strncpy( string, " -ind", 6 ); /* " -1.#IND00"; */
+
+    if( exp_delim == 'r' || exp_delim == 'R' )
+    {
+      strcat( t_string, "_r" );
+    }
+    else if( exp_delim == 'j' || exp_delim == 'J' )
+    {
+      strcat( t_string, "_j" );
+    }
+    /* abort() */
+  }
+
+  if( jc < 0 ) /* Number is greater than 1 (y > 1.0) */
+  {
+    ei_copy( u, y, nb );
+
+    /* u[Exponent] = EXONE + NSBITS - 1 */
+    j = (EMUSHORT)NSBITS(nb);
+    j -= 1;
+    ei_cvte_unpack( inc, (EMUSHORT *)&j, ne+1, 1 );
+    ei_adde( inc, exone, inc, ne+1 );
+    /* Copy Exponents */
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+    ei_cpye_pack( &u[1],    inc,  ne, ne+1 );
+#else
+    ei_cpye_pack( &u[ns+2], inc,  ne, ne+1 );
+#endif
+
+    p = _get_tens_ptr( nb );
+
+    /* if( BITS_PER_EMUSHORT == 16 ) { *p = 10**16; } */
+    /* if( BITS_PER_EMUSHORT == 32 ) { *p = 10**32; } */
+    /* if( BITS_PER_EMUSHORT == 64 ) { *p = 10**64; } */
+    p += np*(n_ten-POW2); /* -POW2 see: mpu-emutype.h */
+
+    j = BITS_PER_EMUSHORT;
+    ei_cvte_unpack( m, (EMUSHORT *)&j, ne+1, 1 ); /* m = BITS_PER_EMUSHORT; */
+
+    do
+    {
+      ei_div( t, u, p, nb );
+      ei_floor( w, t, nb );
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+      for( i = ne+2; i < np-1; i++ )
+#else
+      for( i = 1; i < ns+1; i++ )
+#endif
+      {
+        if( t[i] != w[i] ) goto noint;
+      }
+      ei_copy( u, t, nb );
+      ei_adde( expon, expon, m, ne+1 );
+noint:
+      p += np;
+      ei_shrn( m, m, (unsigned)1, ne+1 ); /* m >>= 1 */
+
+    } while( ei_cmp0e( m, ne+1 ) != 0 );
+
+    /* Rescale from integer Significand */
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+    ei_cpye_unpack( m, &y[1],    ne+1, ne );
+#else
+    ei_cpye_unpack( m, &y[ns+2], ne+1, ne );
+#endif
+
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+    ei_cpye_unpack( n, &u[1],    ne+1, ne );
+#else
+    ei_cpye_unpack( n, &u[ns+2], ne+1, ne );
+#endif
+
+    /* inc еще равно EXONE + NSBITS - 1 */
+    ei_sube( m, m, inc, ne+1 );
+    ei_adde( n, n, m, ne+1 );
+
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+    ei_cpye_pack( &u[1],    n,  ne, ne+1 );
+#else
+    ei_cpye_pack( &u[ns+2], n,  ne, ne+1 );
+#endif
+    /* т.е. u[exp] += y[exp] -(unsigned)(EXONE + NBITS - 1) */
+
+    ei_copy( y, u, nb );
+
+    /* Find power of 10 */
+    /* t = 1.0E0 */
+    _gen_one( t, nb );
+
+    /* m = MAXP */
+    for( i = 0; i < ne+1; i++ ) m[i] = (EMUSHORT)0;
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+    m[1]    = HIGHT_EXMAX_P;
+#else
+    m[ne-1] = HIGHT_EXMAX_P;
+#endif
+
+    p = _get_tens_ptr( nb );
+    /* An unordered compare result shouldn't happen here */
+    while( ei_cmp( ten, u, nb ) <= 0 )
+    {
+      if( ei_cmp( p, u, nb ) <= 0 )
+      {
+        ei_div( u, u, p, nb );
+        ei_mul( t, t, p, nb );
+        ei_adde( expon, expon, m, ne+1 );
+
+      } /* End if( p <= u ) */
+
+      ei_shrn( m, m, (unsigned)1, ne+1 ); /* m >>= 1 */
+      if( ei_cmp0e( m, ne+1 ) == 0 ) break;
+      p += np;
+
+    } /* End of while( ten <= u ) */
+
+  }
+  else        /* Number is less than 1 (y < 1.0) */
+  {
+
+    /* tmp = 1.0E0 */
+    _gen_one( tmp, nb );
+
+    /* Pad Significand with trailing decimal zeros */
+    /* Test for zero Exponent */
+    /* Copy Exponents */
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+    ei_cpye_unpack( inc, &y[1],    ne+1, ne );
+#else
+    ei_cpye_unpack( inc, &y[ns+2], ne+1, ne );
+#endif
+    if( ei_cmp0e( inc, ne+1 ) == 0 ) /* Exponent == 0 */
+    {
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+      while( (y[ne+2] & MASK_SIGN) == 0 )
+#else
+      while( (y[ns]   & MASK_SIGN) == 0 )
+#endif
+      {
+        ei_mul( y, y, ten, nb );
+        ei_dece( expon, expon, ne+1 ); /* expon -= 1; */
+      }
+    }
+    else /* Exponent != 0 */
+    {
+      ei_copy( w, y, nb );
+      for( i = 0; i < n_dec + 1; i++ )
+      {
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+        if( (w[ne+ns+2] & 0x7) != 0 ) /* lgw */
+#else
+        if( (w[0]       & 0x7) != 0 ) /* lgw */
+#endif
+           break;
+
+        /* multiply by 10 */
+        ei_copyzlgw( u, w, nb );
+        ei_shdown( u, (unsigned)2, nb );
+        ei_addm( u, w, u, nb );
+
+        j = 3; /* Exponent += 3 */
+        ei_cvte_unpack( inc, (EMUSHORT *)&j, ne, 1 );
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+        ei_adde( &u[1],    &u[1],    inc, ne );
+#else
+        ei_adde( &u[ns+2], &u[ns+2], inc, ne );
+#endif
+
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+        while( u[ne+1] != (EMUSHORT)0 ) /* hgw != 0 */
+#else
+        while( u[ns+1] != (EMUSHORT)0 ) /* hgw != 0 */
+#endif
+        {
+           ei_shdown( u, (unsigned)1, nb );
+           /* Exponent += 1 */
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+           ei_ince( &u[1],    &u[1],    ne );
+#else
+           ei_ince( &u[ns+2], &u[ns+2], ne );
+#endif
+        }
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+        if( u[ne+ns+2] != (EMUSHORT)0 ) /* lgw != 0 */
+#else
+        if( u[0]       != (EMUSHORT)0 ) /* lgw != 0 */
+#endif
+           break;
+
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+        if( ei_cmpe( &tmp[1],    &u[1],    ne ) <= 0 )
+#else
+        if( ei_cmpe( &tmp[ns+2], &u[ns+2], ne ) <= 0 )
+#endif
+           break;
+
+        ei_copyzlgw( w, u, nb );
+        ei_dece( expon, expon, ne+1 ); /* expon -= 1; */
+
+      } /* End for( i < n_dec ) */
+
+      ei_copy( y, w, nb );
+
+    } /* Enf if( y[Exponent] == 0 ) */
+
+    /* m = - MAXP */
+    for( i = 0; i < ne+1; i++ ) m[i] = (EMUSHORT)0;
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+    m[1]    = HIGHT_EXMAX_P;
+#else
+    m[ne-1] = HIGHT_EXMAX_P;
+#endif
+
+    p = _get_mtens_ptr( nb );
+    r = _get_tens_ptr( nb );
+
+    ei_copy( w, y, nb );
+    ei_copy( t, tmp, nb ); /* t = 1.0 */
+
+    while( ei_cmp( tmp, w, nb ) > 0 )
+    {
+      if( ei_cmp( p, w, nb ) >= 0 )
+      {
+        ei_mul( w, w, r, nb );
+        ei_mul( t, t, r, nb );
+        ei_sube( expon, expon, m, ne+1 ); /* expon -= m; */
+      }
+      ei_shrn( m, m, (unsigned)1, ne+1 ); /* m /= 2; */
+
+      if( ei_cmp0e( m, ne+1 ) == 0 ) break;
+
+      p += np;
+      r += np;
+    }
+
+    ei_div( t, tmp, t, nb ); /* t = 1.0 / t; */
+
+  }
+
+isone:
+
+  /* Find the first (leading) digit */
+  ei_copy( w, t, nb );
+  ei_copyzlgw( t, w, nb );
+  ei_copy( w, y, nb );
+  ei_copyzlgw( y, w, nb );
+
+  ei_remain( y, equot, y, t, nb );
+
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+  digit = equot[ne+ns+2]; /* lgw */
+#else
+  digit = equot[0];       /* lgw */
+#endif
+
+  /* tmp = 0E0 */
+  _gen_zero( tmp, nb );
+
+  while( (digit == 0) && (ei_cmp( y, tmp, nb ) != 0) )
+  {
+    ei_shup( y, (unsigned)1, nb );
+    ei_copyzlgw( u, y, nb );
+    ei_shup( u, (unsigned)2, nb );
+    ei_addm( y, y, u, nb );
+    ei_remain( y, equot, y, t, nb );
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+    digit = equot[ne+ns+2]; /* lgw */
+#else
+    digit = equot[0];       /* lgw */
+#endif
+    ei_dece( expon, expon, ne+1 ); /* expon -= 1; */
+  }
+
+  s = t_string;
+
+  if( sign ) *s++ = '-';
+  else if( gen_plus )   *s++ = '+';
+       else             *s++ = ' ';
+
+  /* Examine number of digits requested by caller */
+  if( ndigs < 0 )     ndigs = 0;
+  if( ndigs > n_dec ) ndigs = (int)n_dec;
+
+  if( digit == 10 )
+  {
+    *s++ = '1';
+    *s++ = '.';
+    if( ndigs > 0 )
+    {
+      *s++ = '0';
+      ndigs -= 1;
+    }
+    ei_ince( expon, expon, ne+1 ); /* expon += 1; */
+  }
+  else
+  {
+    *s++ = (__mpu_char8_t)digit + '0';
+    *s++ = '.';
+  }
+
+  /* Generate digits after the decimal point */
+  for( k = 0; k <= ndigs; k++ )
+  {
+    ei_shup( y, (unsigned)1, nb );
+    ei_copyzlgw( u, y, nb );
+    ei_shup( u, (unsigned)2, nb );
+    ei_addm( y, u, y, nb );
+    ei_remain( y, equot, y, t, nb );
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+    *s++ = (__mpu_char8_t)equot[ne+ns+2] + '0'; /* lgw */
+#else
+    *s++ = (__mpu_char8_t)equot[0]       + '0'; /* lgw */
+#endif
+  }
+
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+  digit = equot[ne+ns+2]; /* lgw */
+#else
+  digit = equot[0];       /* lgw */
+#endif
+
+  --s;
+  ss = s;
+
+  /* Round off the ASCII string */
+  if( digit > 4 )
+  {
+    /* Test for critical rounding case in ASCII output */
+    if( digit == 5 )
+    {
+      ei_copy( t, y, nb );
+      if( ei_cmp( t, tmp, nb ) != 0 ) goto roun;  /* round to nearest */
+      if( (*(s - 1) & 1) == 0 )       goto doexp; /* round to even */
+
+    } /* End if( digit == 5 ) */
+
+    /* Round up and propagate carry-outs */
+roun:
+    --s;
+    k = *s & 0x7f;
+    /* Carry out to most significant digit? */
+    if( k == '.' )
+    {
+      --s;
+      k = *s;
+      k += 1;
+      *s = (__mpu_char8_t)k;
+
+      /* Most significant digit carries to 10? */
+      if( k > '9' )
+      {
+        ei_ince( expon, expon, ne+1 ); /* expon += 1; */
+        *s = '1';
+      }
+      goto doexp;
+    }
+
+    /* Round up and carry out from less significant digits */
+    k += 1;
+    *s = (__mpu_char8_t)k;
+    if( k > '9' )
+    {
+      *s = '0';
+      goto roun;
+    }
+
+  } /* Enf if( digit > 4 ) */
+
+doexp:
+  {
+    __mpu_char8_t  sexp[512];
+    __mpu_char8_t  sexd[4];
+
+    /* Не изменяет флаги: CF, AF, PF, ZF, SF, OF, RF. */
+    iitoa_np( sexp,
+              expon,
+              10, /* radix */
+              0,  /* upper flag */
+              ne+1 );
+    if( exp_digs > 0 )
+    {
+      /*************************************************
+        Если это необходимо, недостающие цифры Exponent
+        будут поставлены как старшие незначащие нули.
+       *************************************************/
+      __mpu_char8_t  stmp[512], *ptr;
+      int            i, len;
+
+      ptr = sexp;
+      if( *ptr == '-' ) ptr++; /* skip sign */
+
+      len = strlen( ptr );
+      if( len < exp_digs )
+      {
+        strcpy( stmp, ptr );
+        len = exp_digs - len;
+        for( i = 0; i < len; i++ ) *ptr++ = '0';
+        *ptr = '\0';
+        strcat( sexp, stmp );
+
+      } /* End if( len < exp_digs ) */
+
+    } /* End if( exp_digs > 0 ) */
+
+    if( ei_cmp0e( expon, ne+1 ) >= 0 )
+    {
+      /* Don't use sprintf() */
+      sexd[0] = (__mpu_char8_t)exp_delim;
+      sexd[1] = '+';
+      sexd[2] = '\0';
+    }
+    else
+    {
+      /* Don't use sprintf() */
+      sexd[0] = (__mpu_char8_t)exp_delim;
+      sexd[1] = '\0';
+    }
+
+    strcpy( ss, sexd ); /* exp_delim */
+    strcat( ss, sexp );
+  }
+
+bxit:
+  rndprc = rndsave;
+  /* Copy out the working string */
+  s  = string;
+  ss = t_string;
+  while( *ss == ' ' ) ++ss; /* Strip possible leading space */
+  while( (*s++ = *ss++) != '\0' )
+    ;
+
+  /* FREE t_string **********/
+  free( t_string );
+  /**************************/
+
+  /* FREE n *****************/
+  /* FREE m *****************/
+  /* FREE expon *************/
+  /* FREE exone *************/
+  /* FREE inc ***************/
+  __mpu_sbrk( -(int)(5*(ne+1)*SIZE_OF_EMUSHORT) );
+  /**************************/
+
+  /* FREE equot *************/
+  /* FREE tmp ***************/
+  /* FREE ten ***************/
+  /* FREE y *****************/
+  /* FREE t *****************/
+  /* FREE u *****************/
+  /* FREE w *****************/
+  __mpu_sbrk( -(int)(7*np*SIZE_OF_EMUSHORT) );
+  /**************************/
+
+} /* End of ei_real_to_ascii() */
+
+
+int ei_ascii_to_real( EMUSHORT *ei, __mpu_char8_t *ss, int nb )
+/***************************************************************
+
+ Description        : ei_ascii_to_real() Работает с
+                                         internal e-type data
+                                         struct.
+
+ Concepts           : Convert ASCII string SS to internal
+                      e-type EI.
+
+                      Return Code:
+                      -1 (ASCII_TO_REAL_ERROR)  - read error;
+                       0 (LONGHAND_REAL_NUMBER) - прочитано простое
+                                                  число (типа 1e1);
+                       1 (REAL_PART_OF_COMPLEX) - прочитана
+                                                  вещественная часть
+                                                  комплексного числа
+                                                  (типа 1r1);
+                       2 (IMAGINARY_OF_COMPLEX) - прочитана мнимая
+                                                  часть комплексного
+                                                  числа
+                                                  (типа 1j1);
+                      NOTE:
+                      ====
+                        Количество цифр, после десятичной точки,
+                        не должно превышать величины
+                        REAL_nnnn_MDEC_DIG + 1 (см.: mpu-floatp.h).
+
+ Use Global Variable:
+
+ Use Functions      :
+                      internal_np( nb );          | mpu-real.c
+                      internal_ne( nb );          | mpu-real.c
+                      internal_ns( nb );          | mpu-real.c
+
+ Parameters         :
+                      EMUSHORT          *ei; - указатель на
+                                               internal e-type
+                                               data struct;
+                      __mpu_char8_t     *ss; - input string;
+                      int                nb; - количество бит в
+                                               external e-type
+                                               data struct.
+
+ Return             : int                rc; - Return Code.
+
+                      if( exp_delim == ('e' || 'E') ) rc =  0;
+                      if( exp_delim == ('r' || 'R') ) rc =  1;
+                      if( exp_delim == ('j' || 'J') ) rc =  2;
+
+                      error:                          rc = -1;
+
+ ***************************************************************/
+{
+  EMUSHORT       *nexp = NULL,
+                 *lexp = NULL,
+                 *dexp = NULL,
+                  *exp = NULL,
+                *exone = NULL,
+                  *inc = NULL,
+
+                   *yy = NULL,
+                   *xt = NULL,
+                   *tt = NULL;
+  EMUSHORT       nsign, *p, *min_dexp, *max_dexp;
+  __mpu_int32_t  j, jc;
+  int            k, trail, c, rndsave, n_ten;
+  int            esign, decflag, signflag, prec, lost;
+  __mpu_char8_t *s, *sp, *lstr = NULL;
+  int            rc     = ASCII_TO_REAL_ERROR,
+                 type_r = LONGHAND_REAL_NUMBER;
+  int            np, ne, ns, i;
+
+
+  errno = 0;
+
+  if( nb < NBR_32 || nb > MPU_REAL_IO_LIMIT )
+  {
+    /* error: Invalid size of operand(s) */
+    __real_error_no = __R_ESIZE__;
+    __STIND; /* Set REAL ind-produsing operation Flag */
+    return( rc );
+  }
+
+  /* Copy the input string */
+  lstr = (__mpu_char8_t *)malloc( strlen( ss ) + 1 );
+  if( !lstr )
+  {
+    /* fatal error */
+    return( rc );
+  }
+  s = ss;
+  while( *s == ' ' ) ++s; /* Skip leading spaces */
+  sp = lstr;
+  while( (*sp++ = *s++) != '\0' )
+    ;
+  s = lstr;
+
+  np = internal_np( nb );
+  ne = internal_ne( nb );
+  ns = internal_ns( nb );
+
+  /*** Allocate memory for nexp, lexp, dexp, exp,
+                        exone, inc . ***********************/
+  nexp = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
+  if( !nexp )
+  {
+    /* fatal error */
+
+    /* FREE lstr **************/
+    free( lstr );
+    /**************************/
+
+    return( rc );
+  }
+
+  lexp = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
+  if( !lexp )
+  {
+    /* fatal error */
+
+    /* FREE lstr **************/
+    free( lstr );
+    /**************************/
+
+    /* FREE nexp **************/
+    __mpu_sbrk( -(int)((ne+1)*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    return( rc );
+  }
+
+  dexp = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
+  if( !dexp )
+  {
+    /* fatal error */
+
+    /* FREE lstr **************/
+    free( lstr );
+    /**************************/
+
+    /* FREE nexp **************/
+    /* FREE lexp **************/
+    __mpu_sbrk( -(int)(2*(ne+1)*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    return( rc );
+  }
+
+  exp = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
+  if( !exp )
+  {
+    /* fatal error */
+
+    /* FREE lstr **************/
+    free( lstr );
+    /**************************/
+
+    /* FREE nexp **************/
+    /* FREE lexp **************/
+    /* FREE dexp **************/
+    __mpu_sbrk( -(int)(3*(ne+1)*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    return( rc );
+  }
+
+  exone = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
+  if( !exone )
+  {
+    /* fatal error */
+
+    /* FREE lstr **************/
+    free( lstr );
+    /**************************/
+
+    /* FREE nexp **************/
+    /* FREE lexp **************/
+    /* FREE dexp **************/
+    /* FREE exp ***************/
+    __mpu_sbrk( -(int)(4*(ne+1)*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    return( rc );
+  }
+
+  inc = (EMUSHORT *)__mpu_sbrk( (int)((ne+1)*SIZE_OF_EMUSHORT) );
+  if( !inc )
+  {
+    /* fatal error */
+
+    /* FREE lstr **************/
+    free( lstr );
+    /**************************/
+
+    /* FREE nexp **************/
+    /* FREE lexp **************/
+    /* FREE dexp **************/
+    /* FREE exp ***************/
+    /* FREE exone *************/
+    __mpu_sbrk( -(int)(5*(ne+1)*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    return( rc );
+  }
+  /************************************************************/
+
+  /*** Allocate memory for yy, xt, tt . ***********************/
+  yy = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
+  if( !yy )
+  {
+    /* fatal error */
+
+    /* FREE lstr **************/
+    free( lstr );
+    /**************************/
+
+    /* FREE nexp **************/
+    /* FREE lexp **************/
+    /* FREE dexp **************/
+    /* FREE exp ***************/
+    /* FREE exone *************/
+    /* FREE inc ***************/
+    __mpu_sbrk( -(int)(6*(ne+1)*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    return( rc );
+  }
+
+  xt = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
+  if( !xt )
+  {
+    /* fatal error */
+
+    /* FREE lstr **************/
+    free( lstr );
+    /**************************/
+
+    /* FREE nexp **************/
+    /* FREE lexp **************/
+    /* FREE dexp **************/
+    /* FREE exp ***************/
+    /* FREE exone *************/
+    /* FREE inc ***************/
+    __mpu_sbrk( -(int)(6*(ne+1)*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    /* FREE yy ****************/
+    __mpu_sbrk( -(int)(np*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    return( rc );
+  }
+
+  tt = (EMUSHORT *)__mpu_sbrk( (int)(np*SIZE_OF_EMUSHORT) );
+  if( !tt )
+  {
+    /* fatal error */
+
+    /* FREE lstr **************/
+    free( lstr );
+    /**************************/
+
+    /* FREE nexp **************/
+    /* FREE lexp **************/
+    /* FREE dexp **************/
+    /* FREE exp ***************/
+    /* FREE exone *************/
+    /* FREE inc ***************/
+    __mpu_sbrk( -(int)(6*(ne+1)*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    /* FREE yy ****************/
+    /* FREE xt ****************/
+    __mpu_sbrk( -(int)(2*np*SIZE_OF_EMUSHORT) );
+    /**************************/
+
+    return( rc );
+  }
+  /************************************************************/
+
+  /* Gen 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
+
+
+  rndsave = rndprc;
+  if( nb == NBR_32 )      rndprc = 24;
+  else if( nb == NBR_64 ) rndprc = 53;
+       else               rndprc = (int)NSBITS( nb );
+
+  lost     = 0;
+  nsign    = (EMUSHORT)0;
+  decflag  = 0;
+  signflag = 0;
+  prec     = 0;
+  for( i = 0; i < ne+1; i++ ) nexp[i] = (EMUSHORT)0;
+  for( i = 0; i < ne+1; i++ )  exp[i] = (EMUSHORT)0;
+  ei_cleaz( yy, nb );
+  trail    = 0;
+
+nextcom:
+  k = *s - '0';
+  if( (k >= 0) && (k <= 9) )
+  {
+    /* Ignore leading zeros */
+    if( (prec == 0) && (decflag == 0) && (k == 0) ) goto donchar;
+
+    /* Identify and strip trailing zeros after the decimal point */
+    if( (trail == 0) && (decflag != 0) )
+    {
+      sp = s;
+      while( (*sp >= '0') && (*sp <= '9') ) ++sp;
+
+      /* check for syntax error */
+      c = *sp & 0x7f; /* Only ASCII code */
+      if( (c != 'e')  && (c != 'E')  &&
+          (c != 'r')  && (c != 'R')  &&
+          (c != 'j')  && (c != 'J')  &&
+          (c != '\n') && (c != '\r') &&
+          (c != '\t') && (c != '\v') &&
+          (c != '\0') &&
+          (c != ' ')  && (c != ',') ) goto errors;
+      --sp;
+      while( *sp == '0' ) *sp-- = 'z';
+      trail = 1;
+      if( *s == 'z' ) goto donchar;
+
+    } /* End if( trail == 0) && (decflag != 0) ) */
+
+    /**************************************************************
+      Продолжая пока не будет что-то записано в hgw, 
+      мы гарантируем, что биты округления после нормализации
+      будут выше lgw.
+     **************************************************************/
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+    if( yy[ne+1] == (EMUSHORT)0 ) /* hgw == 0 */
+#else
+    if( yy[ns+1] == (EMUSHORT)0 ) /* hgw == 0 */
+#endif
+    {
+      /* Count digits after decimal point */
+      if( decflag ) ei_ince( nexp, nexp, ne+1 );
+
+      /* Multiply current number to 10 */
+      ei_shup( yy, (unsigned)1, nb );
+      ei_copyzlgw( xt, yy, nb );
+      ei_shup( xt, (unsigned)2, nb );
+      ei_addm( yy, xt, yy, nb );
+      ei_cleaz( xt, nb );
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+      xt[ne+ns+1] = (EMUSHORT)k; /* low part of Significand */
+#else
+      xt[1]       = (EMUSHORT)k; /* low part of Significand */
+#endif
+      ei_addm( yy, xt, yy, nb );
+    }
+    else /* ( hgw != 0 ) */
+    {
+      /* Marc any lost non-zero digit */
+      lost |= k;
+      /* Count lost digits before the decimal point */
+      if( decflag == 0 ) ei_dece( nexp, nexp, nb );
+
+    } /* End if( hgw == 0 ) */
+
+    prec += 1;
+    goto donchar;
+
+  } /* End if( (k >= 0) && (k <= 9) ) */
+
+  switch( *s )
+  {
+    case 'z':
+      break;
+
+    case 'e':
+    case 'E':
+      goto exponent;
+    case 'r':
+    case 'R':
+      type_r = REAL_PART_OF_COMPLEX;
+      goto exponent;
+    case 'j':
+    case 'J':
+      type_r = IMAGINARY_OF_COMPLEX;
+      goto exponent;
+
+    case '.': /* decimal point */
+      if( decflag ) goto errors;
+      ++decflag;
+      break;
+
+    case '-':
+      nsign = MASK_ALL_BITS;
+      if( signflag ) goto errors;
+      /* Здесь можно пропустить пробелы между знаком и числом: */
+      while( s[1] == ' '  ||
+             s[1] == '\n' ||
+             s[1] == '\r' ||
+             s[1] == '\t' ||
+             s[1] == '\v'    ) ++s;
+      ++signflag;
+      break;
+
+    case '+':
+      if( signflag ) goto errors;
+      /* Здесь можно пропустить пробелы между знаком и числом: */
+      while( s[1] == ' '  ||
+             s[1] == '\n' ||
+             s[1] == '\r' ||
+             s[1] == '\t' ||
+             s[1] == '\v'    ) ++s;
+      ++signflag;
+      break;
+
+    case ',':
+    case ' ':
+    case '\0':
+    case '\n':
+    case '\r':
+    case '\t':
+    case '\v':
+      goto daldone;
+
+    case 'i':
+    case 'I':
+      /* ind ****************************************/
+      if( (s[1] == 'n' || s[1] == 'N') &&
+          (s[2] == 'd' || s[2] == 'D')   )
+      {
+        if( s[3] == '_' )
+        {
+          switch( s[4] )
+          {
+            case 'r':
+            case 'R':
+              type_r = REAL_PART_OF_COMPLEX;
+              break;
+            case 'j':
+            case 'J':
+              type_r = IMAGINARY_OF_COMPLEX;
+              break;
+            case 'e':
+            case 'E':
+              type_r = LONGHAND_REAL_NUMBER;
+              break;
+            default:
+              break;
+          }
+        }
+        /* ind */
+        ei_ind( yy, nb );
+        rndprc = rndsave;
+        goto ind_exit;
+      }
+      /* inf ****************************************/
+      else if( (s[1] == 'n' || s[1] == 'N') &&
+               (s[2] == 'f' || s[2] == 'F')   )
+      {
+        if( s[3] == '_' )
+        {
+          switch( s[4] )
+          {
+            case 'r':
+            case 'R':
+              type_r = REAL_PART_OF_COMPLEX;
+              break;
+            case 'j':
+            case 'J':
+              type_r = IMAGINARY_OF_COMPLEX;
+              break;
+            case 'e':
+            case 'E':
+              type_r = LONGHAND_REAL_NUMBER;
+              break;
+            default:
+              break;
+          }
+        }
+        /* inf */
+        goto infinite;
+      }
+      else
+      /**********************************************/
+        goto errors;
+
+    case 'n':
+    case 'N':
+      /* NaN ****************************************/
+      if( (s[1] == 'a' || s[1] == 'A') &&
+          (s[2] == 'n' || s[2] == 'N') )
+      {
+        if( s[3] == '_' )
+        {
+          switch( s[4] )
+          {
+            case 'r':
+            case 'R':
+              type_r = REAL_PART_OF_COMPLEX;
+              break;
+            case 'j':
+            case 'J':
+              type_r = IMAGINARY_OF_COMPLEX;
+              break;
+            case 'e':
+            case 'E':
+              type_r = LONGHAND_REAL_NUMBER;
+              break;
+            default:
+              break;
+          }
+        }
+        /* nan */
+        ei_nan( yy, (unsigned)nsign, nb );
+        rndprc = rndsave;
+        goto ind_exit;
+      }
+      else
+      /**********************************************/
+        goto errors;
+
+    default:
+errors:
+      type_r = ASCII_TO_REAL_ERROR;
+      ei_nan( yy, (unsigned)0, nb );
+      goto aexit;
+
+  } /* End of switch( *s ) */
+
+donchar:
+  ++s;
+  goto nextcom;
+
+  /*************************
+    Exponent interpretation
+   *************************/
+exponent:
+
+  max_dexp = _get_maxdecexp_ptr( nb ); /* size ne+1 always */
+  min_dexp = _get_mindecexp_ptr( nb ); /* size ne+1 always */
+  ei_cpye_unpack( dexp, min_dexp, ne+1, ne+1 );
+  ei_nege( dexp, dexp, ne+1 ); /* dexp == -(MINDECEXP) */
+
+  esign = 1;
+  ++s;
+
+  /* Check for + or - */
+  if( *s == '-' )
+  {
+    esign = -1;
+    ++s;
+  }
+  if( *s == '+' ) ++s;
+
+  while( (*s >= '0') && (*s <= '9') )
+  {
+    /* exp *= 10; */
+    ei_shln( exp, exp, (unsigned)1, ne+1 );
+    ei_shln( inc, exp, (unsigned)2, ne+1 );
+    ei_adde( exp, inc, exp, ne+1 );
+
+    /* exp += *s++ - '0'; */
+    j = *s++ - '0';
+    ei_cvte_unpack( inc, (EMUSHORT *)&j, ne+1, 1 );
+    ei_adde( exp, exp, inc, ne+1 );
+
+    if( ei_cmpe( exp, dexp, ne+1 ) > 0 ) /* exp > -(MINDECEXP) */
+    {
+      if( esign < 0 ) goto zero;
+      else            goto infinite;
+    }
+
+  } /* End of while( is_digit(*s) ) */
+
+
+  if( esign < 0 ) ei_nege( exp, exp, ne+1 ); /* exp = -exp */
+
+  if( ei_cmpe( exp, max_dexp, ne+1 ) > 0 ) /* exp > (MAXDECEXP) */
+  {
+infinite:
+    ei_infin( yy, (unsigned)nsign, nb ); /* Infinity */
+    goto aexit;
+  }
+
+  if( ei_cmpe( exp, min_dexp, ne+1 ) < 0 ) /* exp < (MINDECEXP) */
+  {
+zero:
+    ei_signull( yy, (unsigned)nsign, nb ); /* signed NULL */
+    goto aexit;
+  }
+
+daldone:
+
+  ei_sube( nexp, exp, nexp, ne+1 );
+
+  /* Pad trailing zeros to minimize power of 10, per IEEE spec. */
+  while( (ei_cmp0e( nexp, ne+1 ) > 0) &&
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+       (yy[ne+1] == (EMUSHORT)0) ) /* hgw == 0 */
+#else
+       (yy[ns+1] == (EMUSHORT)0) ) /* hgw == 0 */
+#endif
+  {
+    ei_copyzlgw( xt, yy, nb );
+    ei_shup( xt, (unsigned)2, nb );
+    ei_addm( xt, yy, xt, nb );
+    ei_shup( xt, (unsigned)1, nb );
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+    if( xt[ne+1] != (EMUSHORT)0 ) break; /* hgw != 0 */
+#else
+    if( xt[ns+1] != (EMUSHORT)0 ) break; /* hgw != 0 */
+#endif
+    ei_dece( nexp, nexp, ne+1 ); /* nexp -= 1; */
+    ei_copyzlgw( yy, xt, nb );
+
+  } /* End of while( (nexp > 0) && (hgw == 0) ) */
+
+  if( (jc = ei_normalize( yy, nb )) > (__mpu_int32_t)NSBITS(nb) )
+  {
+    ei_cleaz( yy, nb );
+    type_r = rc; /* количество цифр после точки превышает размер мантиссы */
+    goto aexit;
+  }
+
+  /* lexp = (EXONE - 1 + NSBITS(nb)) - jc */
+  ei_dece( lexp, exone, ne+1 );
+  j = NSBITS( nb );
+  ei_cvte_unpack(  inc,  (EMUSHORT *)&j, ne+1, 1 );
+  ei_cvte_unpack( dexp, (EMUSHORT *)&jc, ne+1, 1 );
+  ei_adde( lexp, lexp,  inc, ne+1 );
+  ei_sube( lexp, lexp, dexp, ne+1 );
+
+  /*
+    Здесь главное, чтобы параметр int rcontrol не был равен 0,
+    для того чтобы функция ei_mdenorm() использовала, ранее
+    установленное значение RNDPRC
+   */
+  ei_mdenorm( yy, lost, 0, lexp, NSBITS_DEFAULT, nb );
+
+
+  /******************************************
+    Convert GO ON
+   ******************************************/
+
+  /* dexp = MAXP */
+  for( i = 0; i < ne+1; i++ ) dexp[i] = (EMUSHORT)0;
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+  dexp[1]    = HIGHT_EXMAX_P;
+#else
+  dexp[ne-1] = HIGHT_EXMAX_P;
+#endif
+
+  n_ten = _get_nten( nb );
+
+  p = _get_tens_ptr( nb ); /* *p = 10**MAXP */
+
+  /* Copy Exponents */
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+  ei_cpye_unpack( lexp, &yy[1],    ne+1, ne );
+#else
+  ei_cpye_unpack( lexp, &yy[ns+2], ne+1, ne );
+#endif
+
+  if( ei_cmp0e( nexp, ne+1 ) == 0 ) /* nexp == 0 */
+  {
+    j = 0;
+    goto expdone;
+
+  } /* End if( nexp == 0 ) */
+
+  esign = 1;
+  if( ei_cmp0e( nexp, ne+1 )  < 0 ) /* nexp  < 0 */
+  {
+    ei_nege( nexp, nexp, ne+1 );
+    esign = -1;
+    if( ei_cmpe( nexp, dexp, ne+1 ) > 0 ) /* nexp > MAXP */
+    {
+      /* Punt. Can't handle this without 2 divides */
+      ei_copy( tt, p, nb );
+      /* Copy Exponents */
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+      ei_cpye_unpack( inc, &tt[1],    ne+1, ne );
+#else
+      ei_cpye_unpack( inc, &tt[ns+2], ne+1, ne );
+#endif
+      ei_sube( lexp, lexp, inc, ne+1 );
+      j = ei_divm( yy, yy, tt, nb );
+      ei_adde( lexp, lexp, exone, ne+1 );
+      ei_sube( nexp, nexp, dexp, ne+1 );
+    }
+
+  } /* End if( nexp < 0 ) */
+ 
+  p = _get_tens_ptr( nb );
+  p += np*n_ten;
+
+  /* xt = 1.0E0 */
+  _gen_one( xt, nb );
+
+  for( i = 0; i < ne+1; i++ )  exp[i] = (EMUSHORT)0;
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+  exp[ne] = (EMUSHORT)1; /* exp = 1 */
+#else
+  exp[0]  = (EMUSHORT)1; /* exp = 1 */
+#endif
+
+  do
+  {
+    ei_ande( inc, exp, nexp, ne+1 );
+    if( ei_cmp0e( inc, ne+1 ) ) /* if( exp & nexp ) */
+      ei_mul( xt, xt, p, nb );
+    p -= np;
+    ei_adde( exp, exp, exp, ne+1 );
+
+  } while( ei_cmpe( exp, dexp, ne+1 ) <= 0 ); /* exp <= MAXP */
+
+  ei_copy( tt, xt, nb );
+
+  /* Copy Exponent of TT */
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+  ei_cpye_unpack( inc, &tt[1],    ne+1, ne );
+#else
+  ei_cpye_unpack( inc, &tt[ns+2], ne+1, ne );
+#endif
+  if( esign < 0 )
+  {
+    ei_sube( lexp, lexp, inc, ne+1 );
+    j = ei_divm( yy, yy, tt, nb );
+    ei_adde( lexp, lexp, exone, ne+1 );
+  }
+  else
+  {
+    ei_adde( lexp, lexp, inc, ne+1 );
+    j = ei_mulm( yy, yy, tt, nb );
+    ei_sube( lexp, lexp, exone, ne+1 );
+    ei_ince( lexp, lexp, ne+1 ); /* lexp -= EXONE -1; */
+  }
+
+expdone:
+
+  /*
+    Здесь главное, чтобы параметр int rcontrol не был равен 0,
+    для того чтобы функция ei_mdenorm() использовала, ранее
+    установленное значение RNDPRC
+   */
+  ei_mdenorm( yy, (int)j, 0, lexp, NSBITS_DEFAULT, nb );
+
+aexit:
+
+  rndprc = rndsave;
+#if MPU_WORD_ORDER_BIG_ENDIAN == 1
+  yy[0]       = nsign; /* copy Sign */
+#else
+  yy[ne+ns+2] = nsign; /* copy Sign */
+#endif
+
+ind_exit:
+  ei_copy( ei, yy, nb );
+
+  /* FREE lstr **************/
+  free( lstr );
+  /**************************/
+
+  /* FREE nexp **************/
+  /* FREE lexp **************/
+  /* FREE dexp **************/
+  /* FREE exp ***************/
+  /* FREE exone *************/
+  /* FREE inc ***************/
+  __mpu_sbrk( -(int)(6*(ne+1)*SIZE_OF_EMUSHORT) );
+  /**************************/
+
+  /* FREE yy ****************/
+  /* FREE xt ****************/
+  /* FREE tt ****************/
+  __mpu_sbrk( -(int)(3*np*SIZE_OF_EMUSHORT) );
+  /**************************/
+
+  rc = type_r;
+  return( rc );
+
+} /* End of ei_ascii_to_real() */
+
+
+/***************************************************************
+  Hide internal symbols:
+ ***************************************************************/
+
+__mpu_hidden_decl(ei_real_to_ascii);
+__mpu_hidden_decl(ei_ascii_to_real);
+
+/*
+  End of hide internal symbols.
+ ***************************************************************/