version 1.1.1.2, 2000/09/09 14:13:08 |
version 1.1.1.3, 2003/08/25 16:06:34 |
|
|
in base BASE to a float in dest. If BASE is zero, the leading characters |
in base BASE to a float in dest. If BASE is zero, the leading characters |
of STRING is used to figure out the base. |
of STRING is used to figure out the base. |
|
|
Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000 Free Software Foundation, |
Copyright 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002 Free Software |
Inc. |
Foundation, Inc. |
|
|
This file is part of the GNU MP Library. |
This file is part of the GNU MP Library. |
|
|
Line 22 along with the GNU MP Library; see the file COPYING.LI |
|
Line 22 along with the GNU MP Library; see the file COPYING.LI |
|
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
MA 02111-1307, USA. */ |
MA 02111-1307, USA. */ |
|
|
|
#include "config.h" |
|
|
|
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
#include <ctype.h> |
#include <ctype.h> |
|
|
|
#if HAVE_LOCALE_H |
|
#include <locale.h> /* for localeconv */ |
|
#endif |
|
|
#include "gmp.h" |
#include "gmp.h" |
#include "gmp-impl.h" |
#include "gmp-impl.h" |
#include "longlong.h" |
#include "longlong.h" |
|
|
|
|
long int strtol _PROTO ((const char *, char **ptr, int)); |
|
|
|
static int |
static int |
#if __STDC__ |
|
digit_value_in_base (int c, int base) |
digit_value_in_base (int c, int base) |
#else |
|
digit_value_in_base (c, base) |
|
int c; |
|
int base; |
|
#endif |
|
{ |
{ |
int digit; |
int digit; |
|
|
Line 56 digit_value_in_base (c, base) |
|
Line 55 digit_value_in_base (c, base) |
|
return -1; |
return -1; |
} |
} |
|
|
int |
#if HAVE_LOCALECONV |
#if __STDC__ |
/* Avoid memcmp for the usual case that point is one character. Don't |
mpf_set_str (mpf_ptr x, const char *str, int base) |
bother with str+1,point+1,pointlen-1 since those offsets would add to the |
|
code size. */ |
|
#define POINTCMP_FAST(c, str) \ |
|
((c) == point0 \ |
|
&& (pointlen == 1 || memcmp (str, point, pointlen) == 0)) |
|
#define POINTCMP_SMALL(c, str) (memcmp (str, point, pointlen) == 0) |
|
#define POINTLEN (pointlen) |
#else |
#else |
mpf_set_str (x, str, base) |
#define POINTCMP_FAST(c, str) ((c) == '.') |
mpf_ptr x; |
#define POINTCMP_SMALL(c, str) ((c) == '.') |
char *str; |
#define POINTLEN 1 |
int base; |
|
#endif |
#endif |
|
|
|
int |
|
mpf_set_str (mpf_ptr x, const char *str, int base) |
{ |
{ |
size_t str_size; |
size_t str_size; |
char *s, *begs; |
char *s, *begs; |
Line 75 mpf_set_str (x, str, base) |
|
Line 82 mpf_set_str (x, str, base) |
|
char *dotpos = 0; |
char *dotpos = 0; |
int expflag; |
int expflag; |
int decimal_exponent_flag; |
int decimal_exponent_flag; |
|
#if HAVE_LOCALECONV |
|
const char *point = localeconv()->decimal_point; |
|
size_t pointlen = strlen (point); |
|
int point0 = point[0]; |
|
#endif |
TMP_DECL (marker); |
TMP_DECL (marker); |
|
|
TMP_MARK (marker); |
TMP_MARK (marker); |
Line 95 mpf_set_str (x, str, base) |
|
Line 107 mpf_set_str (x, str, base) |
|
decimal_exponent_flag = base < 0; |
decimal_exponent_flag = base < 0; |
base = ABS (base); |
base = ABS (base); |
|
|
if (digit_value_in_base (c, base == 0 ? 10 : base) < 0 |
/* require at least one digit, possibly after an initial decimal point */ |
&& (c != '.' || digit_value_in_base (str[1], base == 0 ? 10 : base) < 0)) |
if (digit_value_in_base (c, base == 0 ? 10 : base) < 0) |
return -1; /* error if no digits */ |
{ |
|
if (! POINTCMP_SMALL (c, str)) |
|
return -1; |
|
if (digit_value_in_base (str[POINTLEN], base == 0 ? 10 : base) < 0) |
|
return -1; |
|
} |
|
|
/* If BASE is 0, try to find out the base by looking at the initial |
/* If BASE is 0, try to find out the base by looking at the initial |
characters. */ |
characters. */ |
Line 141 mpf_set_str (x, str, base) |
|
Line 158 mpf_set_str (x, str, base) |
|
{ |
{ |
int dig; |
int dig; |
|
|
if (c == '.') |
if (POINTCMP_FAST (c, str)) |
{ |
{ |
if (dotpos != 0) |
if (dotpos != 0) |
{ |
{ |
TMP_FREE (marker); |
TMP_FREE (marker); |
return -1; |
return -1; |
} |
} |
dotpos = s; |
dotpos = s; |
|
str += POINTLEN - 1; |
|
i += POINTLEN - 1; |
} |
} |
else |
else |
{ |
{ |
Line 225 mpf_set_str (x, str, base) |
|
Line 244 mpf_set_str (x, str, base) |
|
rp[0] = base; |
rp[0] = base; |
rsize = 1; |
rsize = 1; |
count_leading_zeros (cnt, exp_in_base); |
count_leading_zeros (cnt, exp_in_base); |
for (i = BITS_PER_MP_LIMB - cnt - 2; i >= 0; i--) |
for (i = GMP_LIMB_BITS - cnt - 2; i >= 0; i--) |
{ |
{ |
mpn_mul_n (tp, rp, rp, rsize); |
mpn_sqr_n (tp, rp, rsize); |
rsize = 2 * rsize; |
rsize = 2 * rsize; |
rsize -= tp[rsize - 1] == 0; |
rsize -= tp[rsize - 1] == 0; |
radj <<= 1; |
radj <<= 1; |
Line 271 mpf_set_str (x, str, base) |
|
Line 290 mpf_set_str (x, str, base) |
|
madj -= rsize - msize; |
madj -= rsize - msize; |
msize = rsize; |
msize = rsize; |
} |
} |
count_leading_zeros (cnt, rp[rsize - 1]); |
if ((rp[rsize - 1] & GMP_NUMB_HIGHBIT) == 0) |
if (cnt != 0) |
|
{ |
{ |
mp_limb_t cy; |
mp_limb_t cy; |
|
count_leading_zeros (cnt, rp[rsize - 1]); |
|
cnt -= GMP_NAIL_BITS; |
mpn_lshift (rp, rp, rsize, cnt); |
mpn_lshift (rp, rp, rsize, cnt); |
cy = mpn_lshift (mp, mp, msize, cnt); |
cy = mpn_lshift (mp, mp, msize, cnt); |
if (cy) |
if (cy) |