wcstold implementation

Craig Howland howland@LGSInnovations.com
Thu Jan 22 17:48:00 GMT 2015


On 01/22/2015 11:16 AM, Corinna Vinschen wrote:
> On Jan 22 16:28, Corinna Vinschen wrote:
>
>
> On Jan 22 15:11, Nick Clifton wrote:
>>> Hi Corinna, Hi Yaakov,
>>>
>>>    What do you think of the attached patch for an implementation of
>>>    wcstold() for sizeof (long double) > sizeof (double) ? The patch is
>>>    against the devo sources, but it could be adapted for FSF newlib
>>>    easily enough.  One thing that you might not like is that the
>>>    _wcstold_r implementation calls _strtold and not _strtold_r.  I can
>>>    fix this too if you think that it is worth it.
>> We don't have a _strtold_r function, only _strtold.  Along these lines,
>> I think it should be sufficent to implement wcstold and just skip
>> _wcstold_r.
> Hmm, on second thought.
>
> The _strtold function in ldtoa.c is old, it never sets errno, it doesn't
> take _localeconv_r (ptr)->decimal_point into account...
>
> Maybe we should in fact start with creating an _strtold_r function from
> the _strtod_r function first?
>
I actually have a _strtold_r() function that I did back in 2009 but never quite 
got to the last step of submitting.  I had gotten an updated version of ldtoa.c 
(the present one in Newlib is not David Gay's latest), and made a wrapper for it.

One thing that I did is that the function call for _strtold_r() has an 
additional argument over strtold() to allow it to be called from scanf.  The 
former wants errno set but the latter does not.

It does not, however, have the locale thing, as that was added after I had done it.

I have attached it for discussion and as a possible starting point. The exact 
method by which error or not errno is handled is a question.  As noted, I had 
put it into the _strtold_r() call, rather than having yet another wrapper 
level.  The reasoning is that you already need to add the reentry pointer, so 
another argument different from the standard call is not necessarily a bad thing.

The list mailer bounced with all 3 files, so here are 2, the other will follow.

Craig
-------------- next part --------------
/* David M. Gay's strtopx adapted for use as strtold.  2009 for Newlib.  */
/****************************************************************

The author of this software is David M. Gay.

Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved

Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.

LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.

****************************************************************/

/* Please send bug reports to David M. Gay (dmg at acm dot org,
 * with " at " changed at "@" and " dot " changed to ".").	*/

#include <_ansi.h>
#include <stdlib.h>
#include <string.h>
#if defined(_HAVE_FENV_H)
  #include <fenv.h>
  #pragma STDC FENV_ACCESS ON
#endif
#include <ieee754.h>
#include "mprec.h"
#include "gdtoa.h"

#if !defined(_REENT_ONLY)  /* { */

long double
/*QQ _DEFUN(strtold, (s, endptr), _CONST char *s _AND char **endptr) */
strtold(const char *s, char **endptr)
#if !defined(_LDBL_EQ_DBL)
{
return(_strtold_r(_REENT, 1, s, endptr));
}       
#else  /* _LDBL_EQ_DBL */
/* When long double is the same size as double, call the double function.  */
{
return((long double) _strtod_r(_REENT, s, endptr));
}
#endif

#endif  /* } */

/* The seterrno argument is a flag to permit (non-0) or deny (0) setting errno
 * for appropriate error conditions.  This permits _strtold_r() to either be
 * used as strtold() (so the wrapper), or called by the scanf family of
 * functions--which are not to set errno in the manner that strtold() must.  */
long double
_strtold_r(struct _reent *ptr, const int seterrno, const char *s, char **endptr)
#if !defined(_LDBL_EQ_DBL)  /* { */
{
static const long double  nn=0.L/0.L;	/* NAN */
static const FPI fpi0 = { LDBL_MANT_DIG,
	LDBL_MIN_EXP-LDBL_MANT_DIG, LDBL_MAX_EXP - LDBL_MANT_DIG,
	FPI_Round_near, SI };
/* ULbits are used per __ULong in the bits array to make up the significand */
__ULong bits[(LDBL_MANT_DIG+(ULbits-1))/ULbits];
Long  exp;	/* un-biased (actual) exponent, as returned from strtodg() */
int  k, i;
LDBL_if  ret;
#if defined(_HAVE_FENV_H)  /* { */
  const FPI  *fpi;
  FPI  fpi1;
  int  flt_rounds=FPI_Round_near;
  #ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
  flt_rounds = Flt_Rounds;
  #else /*}{*/
  flt_rounds = FPI_Round_near;
  switch(fegetround()) {
	#if defined(FE_TOWARDZERO)
	case FE_TOWARDZERO:	flt_rounds = FPI_Round_zero; break;
	#endif
	#if defined(FE_UPWARD)
	case FE_UPWARD:	flt_rounds = FPI_Round_up; break;
	#endif
	#if defined(FE_DOWNWARD)
	case FE_DOWNWARD:	flt_rounds = FPI_Round_down;
	#endif
	}
  #endif /*}}*/
  if(flt_rounds != FPI_Round_near) {
	fpi1 = fpi0;
	fpi = &fpi1;
	fpi1.rounding = flt_rounds;
	}
    else  fpi = &fpi0;
#else  /* } { */
  #define fpi &fpi0
#endif  /* } */

ret.f = 0.L;	/* Default return is +0 */
k = strtodg(ptr, s, endptr, fpi, &exp, bits);
switch(k & STRTOG_Retmask) {
	case STRTOG_NoNumber:
	case STRTOG_Zero:
		if(k & STRTOG_Underflow  &&  seterrno)  ptr->_errno = ERANGE;
		/* Do nothing else, as already have done ret.f = +0.L */
		break;

	case STRTOG_Denormal:
		ret.b.exp = 0;
		goto normal_bits;

	case STRTOG_Normal:
	case STRTOG_NaNbits:
		ret.b.exp = exp + LDBL_EXPBIAS + LDBL_MANT_DIG-1;
		normal_bits:
		#if LDBL_FRAC_CNT == 1
		ret.b.frac = bits[0];
		for(i=ULbits; i<LDBL_MANT_DIG; i+=ULbits)
			ret.b.frac |= (LDBL_BF_T) bits[i>>kshift] << i;
		# else
		/* Do not bother with allowing LDBL_BF_LEN < 32, as would not
		 * make any sense for it to be done.  */
		{
		int  extra;
		ret.b.fracls = bits[0];
		for(i=ULbits; i<LDBL_LSW_BITS; i+=ULbits)
			ret.b.fracls |= (LDBL_BF_T) bits[i>>kshift] << i;
		/* If did not use an integral number of bits members to fill
		 * fracls, put the leftovers into fracms.  */
		extra = i - LDBL_LSW_BITS;
		i >>= kshift;	/* Change i from bit count to bits index */
		if(extra)  ret.b.fracms = (LDBL_BF_T) bits[i-1] >> ULbits-extra;
		for(; extra<LDBL_MSW_BITS; extra+=ULbits, i++)
				ret.b.fracms |= (LDBL_BF_T) bits[i] << extra;
		}
		#endif
		break;

	case STRTOG_Infinite:
		if(k & STRTOG_Overflow  &&  seterrno)  ptr->_errno = ERANGE;
		ret.f = HUGE_VALL;
		break;

	case STRTOG_NaN:
		ret.f = nn;
	}
if(k & STRTOG_Neg)  ret.b.sign = 1;
return ret.f;
}
 
#else  /* } { _LDBL_EQ_DBL */
/* When long double is the same size as double, call the double function.  */
{
return((long double) _strtod_r(ptr, s, endptr));
}
#endif  /* } */
-------------- next part --------------
/****************************************************************
 *
 * The author of this software is David M. Gay.
 *
 * Copyright (c) 1991 by AT&T.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose without fee is hereby granted, provided that this entire notice
 * is included in all copies of any software which is or includes a copy
 * or modification of this software and in all copies of the supporting
 * documentation for such software.
 *
 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
 *
 ***************************************************************/

/* Please send bug reports to
	David M. Gay
	AT&T Bell Laboratories, Room 2C-463
	600 Mountain Avenue
	Murray Hill, NJ 07974-2070
	U.S.A.
	dmg@research.att.com or research!dmg
 */

#include <ieeefp.h>
#include <math.h>
#include <float.h>
#include <errno.h>
#include <sys/config.h>
#include <sys/types.h>

#ifdef __IEEE_LITTLE_ENDIAN
#define IEEE_8087
#endif

#ifdef __IEEE_BIG_ENDIAN
#define IEEE_MC68k
#endif

#ifdef __Z8000__
#define Just_16
#endif

#ifdef DEBUG
#include "stdio.h"
#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
#endif

#ifdef Unsigned_Shifts
#define Sign_Extend(a,b) if (b < 0) a |= (__uint32_t)0xffff0000;
#else
#define Sign_Extend(a,b) /*no-op*/
#endif

#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
#endif

/* If we are going to examine or modify specific bits in a double using
   the word0 and/or word1 macros, then we must wrap the double inside
   a union.  This is necessary to avoid undefined behavior according to
   the ANSI C spec.  */
union double_union
{
  double d;
  __uint32_t i[2];
};

#ifdef IEEE_8087
#define word0(x) (x.i[1])
#define word1(x) (x.i[0])
#else
#define word0(x) (x.i[0])
#define word1(x) (x.i[1])
#endif

/* The following is taken from gdtoaimp.h for use with new strtod, but
   adjusted to avoid invalid type-punning.  */
typedef __int32_t Long;

/* Unfortunately, because __ULong might be a different type than
   __uint32_t, we can't re-use union double_union as-is without
   further edits in strtod.c.  */
typedef union { double d; __ULong i[2]; } U;

#define dword0(x) word0(x)
#define dword1(x) word1(x)
#define dval(x) (x.d)

#undef SI
#ifdef Sudden_Underflow
#define SI 1
#else
#define SI 0
#endif

#define Storeinc(a,b,c) (*(a)++ = ((b) << 16) | ((c) & 0xffff))

/* #define P DBL_MANT_DIG */
/* Ten_pmax = floor(P*log(2)/log(5)) */
/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */

#if defined(IEEE_8087) + defined(IEEE_MC68k)
#if defined (_DOUBLE_IS_32BITS) 
#define Exp_shift   23
#define Exp_shift1  23
#define Exp_msk1    ((__uint32_t)0x00800000L)
#define Exp_msk11   ((__uint32_t)0x00800000L)
#define Exp_mask    ((__uint32_t)0x7f800000L)
#define P    	    24
#define Bias 	    127
#define NO_HEX_FP   /* not supported in this case */
#define IEEE_Arith
#define Emin        (-126)
#define Exp_1       ((__uint32_t)0x3f800000L)
#define Exp_11      ((__uint32_t)0x3f800000L)
#define Ebits 	    8
#define Frac_mask   ((__uint32_t)0x007fffffL)
#define Frac_mask1  ((__uint32_t)0x007fffffL)
#define Ten_pmax    10
#define Sign_bit    ((__uint32_t)0x80000000L)
#define Ten_pmax    10
#define Bletch	    2
#define Bndry_mask  ((__uint32_t)0x007fffffL)
#define Bndry_mask1 ((__uint32_t)0x007fffffL)
#define LSB 1
#define Sign_bit    ((__uint32_t)0x80000000L)
#define Log2P 	    1
#define Tiny0 	    0
#define Tiny1 	    1
#define Quick_max   5
#define Int_max     6
#define Infinite(x) (word0(x) == ((__uint32_t)0x7f800000L))
#undef word0
#undef word1
#undef dword0
#undef dword1

#define word0(x) (x.i[0])
#define word1(x) 0
#define dword0(x) word0(x)
#define dword1(x) 0
#else

#define Exp_shift  20
#define Exp_shift1 20
#define Exp_msk1    ((__uint32_t)0x100000L)
#define Exp_msk11   ((__uint32_t)0x100000L)
#define Exp_mask  ((__uint32_t)0x7ff00000L)
#define P 53
#define Bias 1023
#define IEEE_Arith
#define Emin (-1022)
#define Exp_1  ((__uint32_t)0x3ff00000L)
#define Exp_11 ((__uint32_t)0x3ff00000L)
#define Ebits 11
#define Frac_mask  ((__uint32_t)0xfffffL)
#define Frac_mask1 ((__uint32_t)0xfffffL)
#define Ten_pmax 22
#define Bletch 0x10
#define Bndry_mask  ((__uint32_t)0xfffffL)
#define Bndry_mask1 ((__uint32_t)0xfffffL)
#define LSB 1
#define Sign_bit ((__uint32_t)0x80000000L)
#define Log2P 1
#define Tiny0 0
#define Tiny1 1
#define Quick_max 14
#define Int_max 14
#define Infinite(x) (word0(x) == ((__uint32_t)0x7ff00000L)) /* sufficient test for here */

#endif /* !_DOUBLE_IS_32BITS */

#ifndef Flt_Rounds
#ifdef FLT_ROUNDS
#define Flt_Rounds FLT_ROUNDS
#else
#define Flt_Rounds 1
#endif
#endif /*Flt_Rounds*/

#else /* !IEEE_8087 && !IEEE_MC68k */
#undef  Sudden_Underflow
#define Sudden_Underflow
#ifdef IBM
#define Flt_Rounds 0
#define Exp_shift  24
#define Exp_shift1 24
#define Exp_msk1   ((__uint32_t)0x1000000L)
#define Exp_msk11  ((__uint32_t)0x1000000L)
#define Exp_mask  ((__uint32_t)0x7f000000L)
#define P 14
#define Bias 65
#define Exp_1  ((__uint32_t)0x41000000L)
#define Exp_11 ((__uint32_t)0x41000000L)
#define Ebits 8	/* exponent has 7 bits, but 8 is the right value in b2d */
#define Frac_mask  ((__uint32_t)0xffffffL)
#define Frac_mask1 ((__uint32_t)0xffffffL)
#define Bletch 4
#define Ten_pmax 22
#define Bndry_mask  ((__uint32_t)0xefffffL)
#define Bndry_mask1 ((__uint32_t)0xffffffL)
#define LSB 1
#define Sign_bit ((__uint32_t)0x80000000L)
#define Log2P 4
#define Tiny0 ((__uint32_t)0x100000L)
#define Tiny1 0
#define Quick_max 14
#define Int_max 15
#else /* VAX */
#define Flt_Rounds 1
#define Exp_shift  23
#define Exp_shift1 7
#define Exp_msk1    0x80
#define Exp_msk11   ((__uint32_t)0x800000L)
#define Exp_mask  ((__uint32_t)0x7f80L)
#define P 56
#define Bias 129
#define Exp_1  ((__uint32_t)0x40800000L)
#define Exp_11 ((__uint32_t)0x4080L)
#define Ebits 8
#define Frac_mask  ((__uint32_t)0x7fffffL)
#define Frac_mask1 ((__uint32_t)0xffff007fL)
#define Ten_pmax 24
#define Bletch 2
#define Bndry_mask  ((__uint32_t)0xffff007fL)
#define Bndry_mask1 ((__uint32_t)0xffff007fL)
#define LSB ((__uint32_t)0x10000L)
#define Sign_bit ((__uint32_t)0x8000L)
#define Log2P 1
#define Tiny0 0x80
#define Tiny1 0
#define Quick_max 15
#define Int_max 15
#endif
#endif

#ifndef IEEE_Arith
#define ROUND_BIASED
#else
#define Scale_Bit 0x10
#if defined(_DOUBLE_IS_32BITS) && defined(__v800)
#define n_bigtens 2
#else
#define n_bigtens 5
#endif
#endif

#ifdef IBM
#define n_bigtens 3
#endif

#ifdef VAX
#define n_bigtens 2
#endif

#ifndef __NO_INFNAN_CHECK
#define INFNAN_CHECK
#endif

/*
 * NAN_WORD0 and NAN_WORD1 are only referenced in strtod.c.  Prior to
 * 20050115, they used to be hard-wired here (to 0x7ff80000 and 0,
 * respectively), but now are determined by compiling and running
 * qnan.c to generate gd_qnan.h, which specifies d_QNAN0 and d_QNAN1.
 * Formerly gdtoaimp.h recommended supplying suitable -DNAN_WORD0=...
 * and -DNAN_WORD1=...  values if necessary.  This should still work.
 * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.)
 */
#ifdef IEEE_Arith
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#ifndef NAN_WORD0
#define NAN_WORD0 d_QNAN0
#endif
#ifndef NAN_WORD1
#define NAN_WORD1 d_QNAN1
#endif
#else
#define _0 1
#define _1 0
#ifndef NAN_WORD0
#define NAN_WORD0 d_QNAN1
#endif
#ifndef NAN_WORD1
#define NAN_WORD1 d_QNAN0
#endif
#endif
#else
#undef INFNAN_CHECK
#endif

#ifdef RND_PRODQUOT
#define rounded_product(a,b) a = rnd_prod(a, b)
#define rounded_quotient(a,b) a = rnd_quot(a, b)
#ifdef KR_headers
extern double rnd_prod(), rnd_quot();
#else
extern double rnd_prod(double, double), rnd_quot(double, double);
#endif
#else
#define rounded_product(a,b) a *= b
#define rounded_quotient(a,b) a /= b
#endif

#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
#define Big1 ((__uint32_t)0xffffffffL)

#ifndef Just_16
/* When Pack_32 is not defined, we store 16 bits per 32-bit long.
 * This makes some inner loops simpler and sometimes saves work
 * during multiplications, but it often seems to make things slightly
 * slower.  Hence the default is now to store 32 bits per long.
 */

 #ifndef Pack_32
  #define Pack_32
 #endif
#else  /* Just_16 */
 #ifndef Pack_16
  #define Pack_16
 #endif
#endif /* Just_16 */

#ifdef Pack_32
#define ULbits 32
#define kshift 5
#define kmask 31
#define ALL_ON 0xffffffff
#else
#define ULbits 16
#define kshift 4
#define kmask 15
#define ALL_ON 0xffff
#endif

#ifdef __cplusplus
extern "C" double strtod(const char *s00, char **se);
extern "C" char *dtoa(double d, int mode, int ndigits,
			int *decpt, int *sign, char **rve);
#endif


typedef struct _Bigint _Bigint;

#define Balloc	_Balloc
#define Bfree	_Bfree
#define multadd __multadd
#define s2b	__s2b
#define lo0bits __lo0bits
#define hi0bits __hi0bits
#define i2b	__i2b
#define mult	__multiply
#define pow5mult	__pow5mult
#define lshift	__lshift
#define cmp	__mcmp
#define diff	__mdiff
#define ulp 	__ulp
#define b2d	__b2d
#define d2b	__d2b
#define ratio	__ratio
#define any_on	__any_on
#define gethex  __gethex
#define copybits 	__copybits
#define hexnan	__hexnan

#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG)
#define __get_hexdig(x) __hexdig[x] /* NOTE: must evaluate arg only once */
#else /* !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG) */
#define __get_hexdig(x) __hexdig_fun(x)
#endif /* !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG) */

#define tens __mprec_tens
#define bigtens __mprec_bigtens
#define tinytens __mprec_tinytens

#define increment	__increment
#define rshift	__rshift
#define sum	__sum
#define strtodg	__strtodg

struct _reent ;
struct FPI;
double 		_EXFUN(ulp,(double x));
double		_EXFUN(b2d,(_Bigint *a , int *e));
_Bigint *	_EXFUN(Balloc,(struct _reent *p, int k));
void 		_EXFUN(Bfree,(struct _reent *p, _Bigint *v));
_Bigint *	_EXFUN(multadd,(struct _reent *p, _Bigint *, int, int));
_Bigint *	_EXFUN(s2b,(struct _reent *, const char*, int, int, __ULong, int));
_Bigint	*	_EXFUN(i2b,(struct _reent *,int));
_Bigint *	_EXFUN(mult, (struct _reent *, _Bigint *, _Bigint *));
_Bigint *	_EXFUN(pow5mult, (struct _reent *, _Bigint *, int k));
int 		_EXFUN(hi0bits,(__ULong));
int 		_EXFUN(lo0bits,(__ULong *));
_Bigint *	_EXFUN(d2b,(struct _reent *p, double d, int *e, int *bits));
_Bigint *	_EXFUN(lshift,(struct _reent *p, _Bigint *b, int k));
_Bigint *	_EXFUN(diff,(struct _reent *p, _Bigint *a, _Bigint *b));
int		_EXFUN(cmp,(_Bigint *a, _Bigint *b));
<<<<<<< mprec.h
int		_EXFUN(gethex,(struct _reent *p, _CONST char **sp, const struct FPI *fpi, Long *exp, _Bigint **bp, int sign));     
=======
int		_EXFUN(gethex,(struct _reent *p, _CONST char **sp, _CONST struct FPI *fpi, Long *exp, _Bigint **bp, int sign));     
>>>>>>> 1.10
double		_EXFUN(ratio,(_Bigint *a, _Bigint *b));
__ULong		_EXFUN(any_on,(_Bigint *b, int k));
void		_EXFUN(copybits,(__ULong *c, int n, _Bigint *b));
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) || defined(_SMALL_HEXDIG)
unsigned char _EXFUN(__hexdig_fun,(unsigned char));
#endif /* !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG) */
#ifdef INFNAN_CHECK
<<<<<<< mprec.h
int		_EXFUN(hexnan,(_CONST char **sp, const struct FPI *fpi, __ULong *x0));
int		_EXFUN(match,(_CONST char **sp, char *t));
=======
int		_EXFUN(hexnan,(_CONST char **sp, _CONST struct FPI *fpi, __ULong *x0));
>>>>>>> 1.10
#endif
_Bigint *	_EXFUN(increment,(struct _reent *ptr, _Bigint *b));
_Bigint *	_EXFUN(sum,(struct _reent *ptr, _Bigint *a, _Bigint *b));
void		_EXFUN(rshift,(_Bigint *b, int k));
int _EXFUN(strtodg, (struct _reent *ptr, const char *s00, char **se, const struct FPI *fpi, Long *exp, __ULong *bits));


#define Bcopy(x,y) memcpy((char *)&x->_sign, (char *)&y->_sign, y->_wds*sizeof(__Long) + 2*sizeof(int))

extern _CONST double tinytens[];
extern _CONST double bigtens[];
extern _CONST double tens[];
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG)
extern _CONST unsigned char __hexdig[];
#endif /* !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG) */


double _EXFUN(_mprec_log10,(int));


More information about the Newlib mailing list