Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/mingw/mingwex/strtold.c')
-rw-r--r--winsup/mingw/mingwex/strtold.c421
1 files changed, 0 insertions, 421 deletions
diff --git a/winsup/mingw/mingwex/strtold.c b/winsup/mingw/mingwex/strtold.c
deleted file mode 100644
index 3bbcea061..000000000
--- a/winsup/mingw/mingwex/strtold.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/* This file is extracted from S L Moshier's ioldoubl.c,
- * modified for use in MinGW
- *
- * Extended precision arithmetic functions for long double I/O.
- * This program has been placed in the public domain.
- */
-
-
-
-/*
- * Revision history:
- *
- * 5 Jan 84 PDP-11 assembly language version
- * 6 Dec 86 C language version
- * 30 Aug 88 100 digit version, improved rounding
- * 15 May 92 80-bit long double support
- *
- * Author: S. L. Moshier.
- *
- * 6 Oct 02 Modified for MinGW by inlining utility routines,
- * removing global variables and splitting out strtold
- * from _IO_ldtoa and _IO_ldtostr.
- *
- * 4 Feb 04 Reorganize __asctoe64 to fix setting error codes,
- * and handling special chars.
- *
- * Danny Smith <dannysmith@users.sourceforge.net>
- */
-
-#include "math/cephes_emath.h"
-#if NE == 10
-
-/* 1.0E0 */
-static const unsigned short __eone[NE] =
- {0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x3fff,};
-#else
-static const unsigned short __eone[NE] = {
-0, 0000000,0000000,0000000,0100000,0x3fff,};
-#endif
-
-#if NE == 10
-static const unsigned short __etens[NTEN + 1][NE] =
-{
- {0x6576, 0x4a92, 0x804a, 0x153f,
- 0xc94c, 0x979a, 0x8a20, 0x5202, 0xc460, 0x7525,}, /* 10**4096 */
- {0x6a32, 0xce52, 0x329a, 0x28ce,
- 0xa74d, 0x5de4, 0xc53d, 0x3b5d, 0x9e8b, 0x5a92,}, /* 10**2048 */
- {0x526c, 0x50ce, 0xf18b, 0x3d28,
- 0x650d, 0x0c17, 0x8175, 0x7586, 0xc976, 0x4d48,},
- {0x9c66, 0x58f8, 0xbc50, 0x5c54,
- 0xcc65, 0x91c6, 0xa60e, 0xa0ae, 0xe319, 0x46a3,},
- {0x851e, 0xeab7, 0x98fe, 0x901b,
- 0xddbb, 0xde8d, 0x9df9, 0xebfb, 0xaa7e, 0x4351,},
- {0x0235, 0x0137, 0x36b1, 0x336c,
- 0xc66f, 0x8cdf, 0x80e9, 0x47c9, 0x93ba, 0x41a8,},
- {0x50f8, 0x25fb, 0xc76b, 0x6b71,
- 0x3cbf, 0xa6d5, 0xffcf, 0x1f49, 0xc278, 0x40d3,},
- {0x0000, 0x0000, 0x0000, 0x0000,
- 0xf020, 0xb59d, 0x2b70, 0xada8, 0x9dc5, 0x4069,},
- {0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0400, 0xc9bf, 0x8e1b, 0x4034,},
- {0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x2000, 0xbebc, 0x4019,},
- {0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x9c40, 0x400c,},
- {0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0xc800, 0x4005,},
- {0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0xa000, 0x4002,}, /* 10**1 */
-};
-#else
-static const unsigned short __etens[NTEN+1][NE] = {
-{0xc94c,0x979a,0x8a20,0x5202,0xc460,0x7525,},/* 10**4096 */
-{0xa74d,0x5de4,0xc53d,0x3b5d,0x9e8b,0x5a92,},/* 10**2048 */
-{0x650d,0x0c17,0x8175,0x7586,0xc976,0x4d48,},
-{0xcc65,0x91c6,0xa60e,0xa0ae,0xe319,0x46a3,},
-{0xddbc,0xde8d,0x9df9,0xebfb,0xaa7e,0x4351,},
-{0xc66f,0x8cdf,0x80e9,0x47c9,0x93ba,0x41a8,},
-{0x3cbf,0xa6d5,0xffcf,0x1f49,0xc278,0x40d3,},
-{0xf020,0xb59d,0x2b70,0xada8,0x9dc5,0x4069,},
-{0x0000,0x0000,0x0400,0xc9bf,0x8e1b,0x4034,},
-{0x0000,0x0000,0x0000,0x2000,0xbebc,0x4019,},
-{0x0000,0x0000,0x0000,0x0000,0x9c40,0x400c,},
-{0x0000,0x0000,0x0000,0x0000,0xc800,0x4005,},
-{0x0000,0x0000,0x0000,0x0000,0xa000,0x4002,}, /* 10**1 */
-};
-#endif
-
-int __asctoe64(const char * __restrict__ ss, short unsigned int * __restrict__ y)
-{
-unsigned short yy[NI], xt[NI], tt[NI];
-int esign, decflg, nexp, exp, lost;
-int k, c;
-int valid_lead_string = 0;
-int have_non_zero_mant = 0;
-int prec = 0;
-/* int trail = 0; */
-long lexp;
-unsigned short nsign = 0;
-const unsigned short *p;
-char *sp, *lstr;
-char *s;
-
-const char dec_sym = *(localeconv ()->decimal_point);
-
-int lenldstr = 0;
-
-/* Copy the input string. */
-c = strlen (ss) + 2;
-lstr = (char *) alloca (c);
-s = (char *) ss;
-while( isspace ((int)(unsigned char)*s)) /* skip leading spaces */
- {
- ++s;
- ++lenldstr;
- }
-sp = lstr;
-for( k=0; k<c; k++ )
- {
- if( (*sp++ = *s++) == '\0' )
- break;
- }
-*sp = '\0';
-s = lstr;
-
-if (*s == '-')
- {
- nsign = 0xffff;
- ++s;
- }
-else if (*s == '+')
- {
- ++s;
- }
-
-if (_strnicmp("INF", s , 3) == 0)
- {
- valid_lead_string = 1;
- s += 3;
- if ( _strnicmp ("INITY", s, 5) == 0)
- s += 5;
- __ecleaz(yy);
- yy[E] = 0x7fff; /* infinity */
- goto aexit;
- }
-else if(_strnicmp ("NAN", s, 3) == 0)
- {
- valid_lead_string = 1;
- s += 3;
- __enan_NI16( yy );
- goto aexit;
- }
-
-/* FIXME: Handle case of strtold ("NAN(n_char_seq)",endptr) */
-
-/* Now get some digits. */
-lost = 0;
-decflg = 0;
-nexp = 0;
-exp = 0;
-__ecleaz( yy );
-
-/* Ignore leading zeros */
-while (*s == '0')
- {
- valid_lead_string = 1;
- s++;
- }
-
-nxtcom:
-
-k = *s - '0';
-if( (k >= 0) && (k <= 9) )
- {
-#if 0
-/* The use of a special char as a flag for trailing zeroes causes problems when input
- actually contains the char */
-/* Identify and strip trailing zeros after the decimal point. */
- if( (trail == 0) && (decflg != 0) )
- {
- sp = s;
- while( (*sp >= '0') && (*sp <= '9') )
- ++sp;
- --sp;
- while( *sp == '0' )
- {
- *sp-- = (char)-1;
- trail++;
- }
- if( *s == (char)-1 )
- goto donchr;
- }
-#endif
-
-/* If enough digits were given to more than fill up the yy register,
- * continuing until overflow into the high guard word yy[2]
- * guarantees that there will be a roundoff bit at the top
- * of the low guard word after normalization.
- */
- if( yy[2] == 0 )
- {
- if( decflg )
- nexp += 1; /* count digits after decimal point */
- __eshup1( yy ); /* multiply current number by 10 */
- __emovz( yy, xt );
- __eshup1( xt );
- __eshup1( xt );
- __eaddm( xt, yy );
- __ecleaz( xt );
- xt[NI-2] = (unsigned short )k;
- __eaddm( xt, yy );
- }
- else
- {
- /* Mark any lost non-zero digit. */
- lost |= k;
- /* Count lost digits before the decimal point. */
- if (decflg == 0)
- nexp -= 1;
- }
- have_non_zero_mant |= k;
- prec ++;
- /* goto donchr; */
- }
-else if (*s == dec_sym)
- {
- if( decflg )
- goto daldone;
- ++decflg;
- }
-else if ((*s == 'E') || (*s == 'e') )
- {
- if (prec || valid_lead_string)
- goto expnt;
- else
- goto daldone;
- }
-
-#if 0
-else if (*s == (char)-1)
- goto donchr;
-#endif
-
-else /* an invalid char */
- goto daldone;
-
-/* donchr: */
-++s;
-goto nxtcom;
-
-
-/* Exponent interpretation */
-expnt:
-
-esign = 1;
-exp = 0;
-/* Save position in case we need to fall back. */
-sp = s;
-++s;
-/* check for + or - */
-if( *s == '-' )
- {
- esign = -1;
- ++s;
- }
-if( *s == '+' )
- ++s;
-
-/* Check for valid exponent. */
-if (!(*s >= '0' && *s <= '9'))
- {
- s = sp;
- goto daldone;
- }
-
-while( (*s >= '0') && (*s <= '9') )
-{
- /* Stop modifying exp if we are going to overflow anyway,
- but keep parsing the string. */
- if (exp < 4978)
- {
- exp *= 10;
- exp += *s - '0';
- }
- s++;
-}
-
-if( esign < 0 )
- exp = -exp;
-
-if (exp > 4977) /* maybe overflow */
- {
- __ecleaz(yy);
- if (have_non_zero_mant)
- yy[E] = 0x7fff;
- goto aexit;
- }
-else if (exp < -4977) /* underflow */
- {
- __ecleaz(yy);
- goto aexit;
- }
-
-daldone:
-
-nexp = exp - nexp;
-
-/* Pad trailing zeros to minimize power of 10, per IEEE spec. */
-while( (nexp > 0) && (yy[2] == 0) )
- {
- __emovz( yy, xt );
- __eshup1( xt );
- __eshup1( xt );
- __eaddm( yy, xt );
- __eshup1( xt );
- if( xt[2] != 0 )
- break;
- nexp -= 1;
- __emovz( xt, yy );
- }
-if( (k = __enormlz(yy)) > NBITS )
- {
- __ecleaz(yy);
- goto aexit;
- }
-lexp = (EXONE - 1 + NBITS) - k;
-__emdnorm( yy, lost, 0, lexp, 64, NBITS );
-/* convert to external format */
-
-
-/* Multiply by 10**nexp. If precision is 64 bits,
- * the maximum relative error incurred in forming 10**n
- * for 0 <= n <= 324 is 8.2e-20, at 10**180.
- * For 0 <= n <= 999, the peak relative error is 1.4e-19 at 10**947.
- * For 0 >= n >= -999, it is -1.55e-19 at 10**-435.
- */
-lexp = yy[E];
-if( nexp == 0 )
- {
- k = 0;
- goto expdon;
- }
-esign = 1;
-if( nexp < 0 )
- {
- nexp = -nexp;
- esign = -1;
- if( nexp > 4096 )
- { /* Punt. Can't handle this without 2 divides. */
- __emovi( __etens[0], tt );
- lexp -= tt[E];
- k = __edivm( tt, yy );
- lexp += EXONE;
- nexp -= 4096;
- }
- }
-p = &__etens[NTEN][0];
-__emov( __eone, xt );
-exp = 1;
-do
- {
- if( exp & nexp )
- __emul( p, xt, xt );
- p -= NE;
- exp = exp + exp;
- }
-while( exp <= MAXP );
-
-__emovi( xt, tt );
-if( esign < 0 )
- {
- lexp -= tt[E];
- k = __edivm( tt, yy );
- lexp += EXONE;
- }
-else
- {
- lexp += tt[E];
- k = __emulm( tt, yy );
- lexp -= EXONE - 1;
- }
-
-expdon:
-
-/* Round and convert directly to the destination type */
-
-__emdnorm( yy, k, 0, lexp, 64, 64 );
-
-aexit:
-
-yy[0] = nsign;
-
-__toe64( yy, y );
-
-/* Check for overflow, undeflow */
-if (have_non_zero_mant &&
- (*((long double*) y) == 0.0L || isinf (*((long double*) y))))
- errno = ERANGE;
-
-if (prec || valid_lead_string)
- return (lenldstr + (s - lstr));
-return 0;
-}
-
-
-long double strtold (const char * __restrict__ s, char ** __restrict__ se)
-{
- int lenldstr;
- union
- {
- unsigned short int us[6];
- long double ld;
- } xx = {{0}};
-
- lenldstr = __asctoe64( s, xx.us);
- if (se)
- *se = (char*)s + lenldstr;
-
- return xx.ld;
-}