Back to index

glibc  2.9
Defines | Functions | Variables
strtod_l.c File Reference
#include <xlocale.h>
#include <math_ldbl_opt.h>
#include <ctype.h>
#include <errno.h>
#include <float.h>
#include <ieee754.h>
#include "../locale/localeinfo.h"
#include <locale.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <gmp-mparam.h>
#include <gmp.h>
#include "gmp-impl.h"
#include "longlong.h"
#include "fpioconst.h"
#include <assert.h>
#include "grouping.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define FLOAT   double
#define FLT   DBL
#define STRTOF   strtod_l
#define __STRTOF   __strtod_l
#define MPN2FLOAT   __mpn_construct_double
#define FLOAT_HUGE_VAL   HUGE_VAL
#define SET_MANTISSA(flt, mant)
#define HAVE_ALLOCA   1
#define NDEBUG   1
#define _NL_CURRENT(category, item)   (current->values[_NL_ITEM_INDEX (item)].string)
#define _NL_CURRENT_WORD(category, item)   ((uint32_t) current->values[_NL_ITEM_INDEX (item)].word)
#define STRING_TYPE   char
#define CHAR_TYPE   char
#define L_(Ch)   Ch
#define ISSPACE(Ch)   __isspace_l ((Ch), loc)
#define ISDIGIT(Ch)   __isdigit_l ((Ch), loc)
#define ISXDIGIT(Ch)   __isxdigit_l ((Ch), loc)
#define TOLOWER(Ch)   __tolower_l ((Ch), loc)
#define TOLOWER_C(Ch)   __tolower_l ((Ch), _nl_C_locobj_ptr)
#define STRNCASECMP(S1, S2, N)   __strncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr)
#define STRTOULL(S, E, B)   ____strtoull_l_internal ((S), (E), (B), 0, loc)
#define MANT_DIG   PASTE(FLT,_MANT_DIG)
#define DIG   PASTE(FLT,_DIG)
#define MAX_EXP   PASTE(FLT,_MAX_EXP)
#define MIN_EXP   PASTE(FLT,_MIN_EXP)
#define MAX_10_EXP   PASTE(FLT,_MAX_10_EXP)
#define MIN_10_EXP   PASTE(FLT,_MIN_10_EXP)
#define PASTE(a, b)   PASTE1(a,b)
#define PASTE1(a, b)   a##b
#define howmany(x, y)   (((x)+((y)-1))/(y))
#define SWAP(x, y)   ({ typeof(x) _tmp = x; x = y; y = _tmp; })
#define NDIG   (MAX_10_EXP - MIN_10_EXP + 2 * MANT_DIG)
#define HEXNDIG   ((MAX_EXP - MIN_EXP + 7) / 8 + 2 * MANT_DIG)
#define RETURN_LIMB_SIZE   howmany (MANT_DIG, BITS_PER_MP_LIMB)
#define RETURN(val, end)
#define MPNSIZE
#define MPN_VAR(name)   mp_limb_t name[MPNSIZE]; mp_size_t name##size
#define MPN_ASSIGN(dst, src)   memcpy (dst, src, (dst##size = src##size) * sizeof (mp_limb_t))
#define DENORM_EXP   (MIN_EXP - 2)
#define INTERNAL(x)   INTERNAL1(x)
#define INTERNAL1(x)   __##x##_internal
#define ____STRTOF_INTERNAL   INTERNAL (__STRTOF)
#define got_limb

Functions

double ____strtod_l_internal (const char *, char **, int, __locale_t)
unsigned long long int ____strtoull_l_internal (const char *, char **, int, int, __locale_t)
FLOAT MPN2FLOAT (mp_srcptr mpn, int exponent, int negative)
static FLOAT round_and_return (mp_limb_t *retval, int exponent, int negative, mp_limb_t round_limb, mp_size_t round_bit, int more_bits)
static const STRING_TYPEstr_to_mpn (const STRING_TYPE *str, int digcnt, mp_limb_t *n, mp_size_t *nsize, int *exponent, const char *decimal, size_t decimal_len, const char *thousands)
static void __attribute ((always_inline))

Variables

const mp_limb_t _tens_in_limb [MAX_DIG_PER_LIMB+1]
FLOAT const STRING_TYPEnptr
STRING_TYPE ** endptr
int group
__locale_t loc

Define Documentation

Definition at line 396 of file strtod_l.c.

#define __STRTOF   __strtod_l

Definition at line 40 of file strtod_l.c.

#define _NL_CURRENT (   category,
  item 
)    (current->values[_NL_ITEM_INDEX (item)].string)

Definition at line 86 of file strtod_l.c.

#define _NL_CURRENT_WORD (   category,
  item 
)    ((uint32_t) current->values[_NL_ITEM_INDEX (item)].word)

Definition at line 89 of file strtod_l.c.

#define CHAR_TYPE   char

Definition at line 111 of file strtod_l.c.

#define DENORM_EXP   (MIN_EXP - 2)
#define DIG   PASTE(FLT,_DIG)

Definition at line 126 of file strtod_l.c.

#define FLOAT   double

Definition at line 33 of file strtod_l.c.

#define FLOAT_HUGE_VAL   HUGE_VAL

Definition at line 43 of file strtod_l.c.

#define FLT   DBL

Definition at line 34 of file strtod_l.c.

#define got_limb
#define HAVE_ALLOCA   1

Definition at line 67 of file strtod_l.c.

#define HEXNDIG   ((MAX_EXP - MIN_EXP + 7) / 8 + 2 * MANT_DIG)

Definition at line 159 of file strtod_l.c.

#define howmany (   x,
  y 
)    (((x)+((y)-1))/(y))

Definition at line 154 of file strtod_l.c.

#define INTERNAL (   x)    INTERNAL1(x)

Definition at line 393 of file strtod_l.c.

#define INTERNAL1 (   x)    __##x##_internal

Definition at line 394 of file strtod_l.c.

#define ISDIGIT (   Ch)    __isdigit_l ((Ch), loc)

Definition at line 114 of file strtod_l.c.

#define ISSPACE (   Ch)    __isspace_l ((Ch), loc)

Definition at line 113 of file strtod_l.c.

#define ISXDIGIT (   Ch)    __isxdigit_l ((Ch), loc)

Definition at line 115 of file strtod_l.c.

#define L_ (   Ch)    Ch

Definition at line 112 of file strtod_l.c.

#define MANT_DIG   PASTE(FLT,_MANT_DIG)

Definition at line 125 of file strtod_l.c.

#define MAX_10_EXP   PASTE(FLT,_MAX_10_EXP)

Definition at line 129 of file strtod_l.c.

#define MAX_EXP   PASTE(FLT,_MAX_EXP)

Definition at line 127 of file strtod_l.c.

#define MIN_10_EXP   PASTE(FLT,_MIN_10_EXP)

Definition at line 130 of file strtod_l.c.

#define MIN_EXP   PASTE(FLT,_MIN_EXP)

Definition at line 128 of file strtod_l.c.

Definition at line 42 of file strtod_l.c.

#define MPN_ASSIGN (   dst,
  src 
)    memcpy (dst, src, (dst##size = src##size) * sizeof (mp_limb_t))

Definition at line 172 of file strtod_l.c.

#define MPN_VAR (   name)    mp_limb_t name[MPNSIZE]; mp_size_t name##size

Definition at line 170 of file strtod_l.c.

#define MPNSIZE
Value:

Definition at line 167 of file strtod_l.c.

#define NDEBUG   1

Definition at line 77 of file strtod_l.c.

#define NDIG   (MAX_10_EXP - MIN_10_EXP + 2 * MANT_DIG)

Definition at line 158 of file strtod_l.c.

#define PASTE (   a,
  b 
)    PASTE1(a,b)

Definition at line 133 of file strtod_l.c.

#define PASTE1 (   a,
  b 
)    a##b

Definition at line 134 of file strtod_l.c.

#define RETURN (   val,
  end 
)
Value:
do { if (endptr != NULL) *endptr = (STRING_TYPE *) (end);                   \
        return val; } while (0)

Definition at line 162 of file strtod_l.c.

Definition at line 160 of file strtod_l.c.

#define SET_MANTISSA (   flt,
  mant 
)
Value:
do { union ieee754_double u;                                                \
       u.d = (flt);                                                  \
       if ((mant & 0xfffffffffffffULL) == 0)                                \
        mant = 0x8000000000000ULL;                                   \
       u.ieee.mantissa0 = ((mant) >> 32) & 0xfffff;                         \
       u.ieee.mantissa1 = (mant) & 0xffffffff;                              \
       (flt) = u.d;                                                  \
  } while (0)

Definition at line 44 of file strtod_l.c.

#define STRING_TYPE   char

Definition at line 110 of file strtod_l.c.

#define STRNCASECMP (   S1,
  S2,
  N 
)    __strncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr)

Definition at line 118 of file strtod_l.c.

#define STRTOF   strtod_l

Definition at line 39 of file strtod_l.c.

#define STRTOULL (   S,
  E,
  B 
)    ____strtoull_l_internal ((S), (E), (B), 0, loc)

Definition at line 120 of file strtod_l.c.

#define SWAP (   x,
  y 
)    ({ typeof(x) _tmp = x; x = y; y = _tmp; })

Definition at line 156 of file strtod_l.c.

#define TOLOWER (   Ch)    __tolower_l ((Ch), loc)

Definition at line 116 of file strtod_l.c.

#define TOLOWER_C (   Ch)    __tolower_l ((Ch), _nl_C_locobj_ptr)

Definition at line 117 of file strtod_l.c.


Function Documentation

double ____strtod_l_internal ( const char *  ,
char **  ,
int  ,
__locale_t   
)
unsigned long long int ____strtoull_l_internal ( const char *  ,
char **  ,
int  ,
int  ,
__locale_t   
)
static void __attribute ( (always_inline)  ) [inline, static]

Definition at line 372 of file strtod_l.c.

{
  if (__builtin_constant_p (count) && count == BITS_PER_MP_LIMB)
    {
      /* Optimize the case of shifting by exactly a word:
        just copy words, with no actual bit-shifting.  */
      mp_size_t i;
      for (i = size - 1; i > 0; --i)
       ptr[i] = ptr[i - 1];
      ptr[0] = limb;
    }
  else
    {
      (void) __mpn_lshift (ptr, ptr, size, count);
      ptr[0] |= limb >> (BITS_PER_MP_LIMB - count);
    }
}
FLOAT MPN2FLOAT ( mp_srcptr  mpn,
int  exponent,
int  negative 
)
static FLOAT round_and_return ( mp_limb_t retval,
int  exponent,
int  negative,
mp_limb_t  round_limb,
mp_size_t  round_bit,
int  more_bits 
) [static]

Definition at line 179 of file strtod_l.c.

{
  if (exponent < MIN_EXP - 1)
    {
      mp_size_t shift = MIN_EXP - 1 - exponent;

      if (shift > MANT_DIG)
       {
         __set_errno (EDOM);
         return 0.0;
       }

      more_bits |= (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0;
      if (shift == MANT_DIG)
       /* This is a special case to handle the very seldom case where
          the mantissa will be empty after the shift.  */
       {
         int i;

         round_limb = retval[RETURN_LIMB_SIZE - 1];
         round_bit = (MANT_DIG - 1) % BITS_PER_MP_LIMB;
         for (i = 0; i < RETURN_LIMB_SIZE; ++i)
           more_bits |= retval[i] != 0;
         MPN_ZERO (retval, RETURN_LIMB_SIZE);
       }
      else if (shift >= BITS_PER_MP_LIMB)
       {
         int i;

         round_limb = retval[(shift - 1) / BITS_PER_MP_LIMB];
         round_bit = (shift - 1) % BITS_PER_MP_LIMB;
         for (i = 0; i < (shift - 1) / BITS_PER_MP_LIMB; ++i)
           more_bits |= retval[i] != 0;
         more_bits |= ((round_limb & ((((mp_limb_t) 1) << round_bit) - 1))
                     != 0);

         (void) __mpn_rshift (retval, &retval[shift / BITS_PER_MP_LIMB],
                               RETURN_LIMB_SIZE - (shift / BITS_PER_MP_LIMB),
                               shift % BITS_PER_MP_LIMB);
          MPN_ZERO (&retval[RETURN_LIMB_SIZE - (shift / BITS_PER_MP_LIMB)],
                    shift / BITS_PER_MP_LIMB);
       }
      else if (shift > 0)
       {
          round_limb = retval[0];
          round_bit = shift - 1;
         (void) __mpn_rshift (retval, retval, RETURN_LIMB_SIZE, shift);
       }
      /* This is a hook for the m68k long double format, where the
        exponent bias is the same for normalized and denormalized
        numbers.  */
#ifndef DENORM_EXP
# define DENORM_EXP (MIN_EXP - 2)
#endif
      exponent = DENORM_EXP;
    }

  if ((round_limb & (((mp_limb_t) 1) << round_bit)) != 0
      && (more_bits || (retval[0] & 1) != 0
          || (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0))
    {
      mp_limb_t cy = __mpn_add_1 (retval, retval, RETURN_LIMB_SIZE, 1);

      if (((MANT_DIG % BITS_PER_MP_LIMB) == 0 && cy) ||
          ((MANT_DIG % BITS_PER_MP_LIMB) != 0 &&
           (retval[RETURN_LIMB_SIZE - 1]
            & (((mp_limb_t) 1) << (MANT_DIG % BITS_PER_MP_LIMB))) != 0))
       {
         ++exponent;
         (void) __mpn_rshift (retval, retval, RETURN_LIMB_SIZE, 1);
         retval[RETURN_LIMB_SIZE - 1]
           |= ((mp_limb_t) 1) << ((MANT_DIG - 1) % BITS_PER_MP_LIMB);
       }
      else if (exponent == DENORM_EXP
              && (retval[RETURN_LIMB_SIZE - 1]
                 & (((mp_limb_t) 1) << ((MANT_DIG - 1) % BITS_PER_MP_LIMB)))
              != 0)
         /* The number was denormalized but now normalized.  */
       exponent = MIN_EXP - 1;
    }

  if (exponent > MAX_EXP)
    return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;

  return MPN2FLOAT (retval, exponent, negative);
}
static const STRING_TYPE* str_to_mpn ( const STRING_TYPE str,
int  digcnt,
mp_limb_t n,
mp_size_t nsize,
int exponent,
const char *  decimal,
size_t  decimal_len,
const char *  thousands 
) [static]

Definition at line 274 of file strtod_l.c.

{
  /* Number of digits for actual limb.  */
  int cnt = 0;
  mp_limb_t low = 0;
  mp_limb_t start;

  *nsize = 0;
  assert (digcnt > 0);
  do
    {
      if (cnt == MAX_DIG_PER_LIMB)
       {
         if (*nsize == 0)
           {
             n[0] = low;
             *nsize = 1;
           }
         else
           {
             mp_limb_t cy;
             cy = __mpn_mul_1 (n, n, *nsize, MAX_FAC_PER_LIMB);
             cy += __mpn_add_1 (n, n, *nsize, low);
             if (cy != 0)
              {
                n[*nsize] = cy;
                ++(*nsize);
              }
           }
         cnt = 0;
         low = 0;
       }

      /* There might be thousands separators or radix characters in
        the string.  But these all can be ignored because we know the
        format of the number is correct and we have an exact number
        of characters to read.  */
#ifdef USE_WIDE_CHAR
      if (*str < L'0' || *str > L'9')
       ++str;
#else
      if (*str < '0' || *str > '9')
       {
         int inner = 0;
         if (thousands != NULL && *str == *thousands
             && ({ for (inner = 1; thousands[inner] != '\0'; ++inner)
                    if (thousands[inner] != str[inner])
                     break;
                  thousands[inner] == '\0'; }))
           str += inner;
         else
           str += decimal_len;
       }
#endif
      low = low * 10 + *str++ - L_('0');
      ++cnt;
    }
  while (--digcnt > 0);

  if (*exponent > 0 && cnt + *exponent <= MAX_DIG_PER_LIMB)
    {
      low *= _tens_in_limb[*exponent];
      start = _tens_in_limb[cnt + *exponent];
      *exponent = 0;
    }
  else
    start = _tens_in_limb[cnt];

  if (*nsize == 0)
    {
      n[0] = low;
      *nsize = 1;
    }
  else
    {
      mp_limb_t cy;
      cy = __mpn_mul_1 (n, n, *nsize, start);
      cy += __mpn_add_1 (n, n, *nsize, low);
      if (cy != 0)
       n[(*nsize)++] = cy;
    }

  return str;
}

Variable Documentation

const mp_limb_t _tens_in_limb[MAX_DIG_PER_LIMB+1]

Definition at line 17 of file tens_in_limb.c.

Definition at line 411 of file strtod_l.c.

Definition at line 412 of file strtod_l.c.

Definition at line 413 of file strtod_l.c.

Definition at line 410 of file strtod_l.c.