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:
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.
+ ***************************************************************/