mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-22 02:40:08 +00:00
Fri Mar 17 13:28:04 1995 Ulrich Drepper <drepper@ipd.info.uni-karlsruhe.de>
* sysdeps/ieee754/ldbl2mpn.c (__mpn_extract_long_double): Handle 80-bit denormalized numbers correct. * stdlib/strtod.c,stdlib/strtof.c,stdlib/strtold.c: [IMPLICIT_ONE,*_MAX_10_EXP_LOG]: not needed anymore. * stdlib/strtod.c (RETURN): parenthesis around return value. (round_and_return): correct handling of denormalized numbers. (__strtod_internal): don't check for grouping when not requested while returning 0.0. * stdio/fpioconst.[ch]: [LDBL_MAX_10_EXP_LOG]: don't use it. LAST_POW10 defines the maximal available exponent. * stdlib/{atof,atoi,atol}.c: use __strtoX_internal.
This commit is contained in:
parent
61cd9516c2
commit
b3fe135050
17
ChangeLog
17
ChangeLog
@ -1,3 +1,20 @@
|
||||
Fri Mar 17 13:28:04 1995 Ulrich Drepper <drepper@ipd.info.uni-karlsruhe.de>
|
||||
|
||||
* sysdeps/ieee754/ldbl2mpn.c (__mpn_extract_long_double):
|
||||
Handle 80-bit denormalized numbers correct.
|
||||
|
||||
* stdlib/strtod.c,stdlib/strtof.c,stdlib/strtold.c:
|
||||
[IMPLICIT_ONE,*_MAX_10_EXP_LOG]: not needed anymore.
|
||||
* stdlib/strtod.c (RETURN): parenthesis around return value.
|
||||
(round_and_return): correct handling of denormalized numbers.
|
||||
(__strtod_internal): don't check for grouping when not requested
|
||||
while returning 0.0.
|
||||
|
||||
* stdio/fpioconst.[ch]: [LDBL_MAX_10_EXP_LOG]: don't use it.
|
||||
LAST_POW10 defines the maximal available exponent.
|
||||
|
||||
* stdlib/{atof,atoi,atol}.c: use __strtoX_internal.
|
||||
|
||||
Thu Mar 16 00:04:41 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
|
||||
|
||||
* locale/C-ctype.c: New correct data generated by drepper.
|
||||
|
@ -196,7 +196,8 @@ static const mp_limb _ten_p12[] =
|
||||
0xae7be4a2, 0x271133ee, 0xbb0fd922, 0x25254932, 0xa60a9fc0, 0x104bcd64,
|
||||
0x30290145, 0x00000062 };
|
||||
|
||||
#define LAST_POW10 12
|
||||
/* This value is the index of the last array element. */
|
||||
#define _LAST_POW10 12
|
||||
|
||||
#elif BITS_PER_MP_LIMB == 64
|
||||
|
||||
@ -369,7 +370,8 @@ static const mp_limb _ten_p12[] =
|
||||
0x271133eeae7be4a2, 0x25254932bb0fd922, 0x104bcd64a60a9fc0,
|
||||
0x0000006230290145 };
|
||||
|
||||
#define LAST_POW10 12
|
||||
/* This value is the index of the last array element. */
|
||||
#define _LAST_POW10 12
|
||||
|
||||
#else
|
||||
# error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
|
||||
@ -379,23 +381,23 @@ static const mp_limb _ten_p12[] =
|
||||
/* Each of array variable above defines one mpn integer which is a power of 10.
|
||||
This table points to those variables, indexed by the exponent. */
|
||||
|
||||
const struct mp_power _fpioconst_pow10[LDBL_MAX_10_EXP_LOG + 1] =
|
||||
const struct mp_power _fpioconst_pow10[_LAST_POW10 + 1] =
|
||||
{
|
||||
{ _ten_p0, sizeof (_ten_p0) / sizeof (_ten_p0[0]), 4, },
|
||||
{ _ten_p1, sizeof (_ten_p1) / sizeof (_ten_p0[1]), 7, 4 },
|
||||
{ _ten_p2, sizeof (_ten_p2) / sizeof (_ten_p0[2]), 14, 10 },
|
||||
{ _ten_p3, sizeof (_ten_p3) / sizeof (_ten_p0[3]), 27, 24 },
|
||||
{ _ten_p4, sizeof (_ten_p4) / sizeof (_ten_p0[4]), 54, 50 },
|
||||
{ _ten_p5, sizeof (_ten_p5) / sizeof (_ten_p0[5]), 107, 103 },
|
||||
{ _ten_p6, sizeof (_ten_p6) / sizeof (_ten_p0[6]), 213, 210 },
|
||||
{ _ten_p7, sizeof (_ten_p7) / sizeof (_ten_p0[7]), 426, 422 },
|
||||
{ _ten_p8, sizeof (_ten_p8) / sizeof (_ten_p0[8]), 851, 848 },
|
||||
{ _ten_p9, sizeof (_ten_p9) / sizeof (_ten_p0[9]), 1701, 1698 },
|
||||
{ _ten_p10, sizeof (_ten_p10) / sizeof (_ten_p0[10]), 3402, 3399 },
|
||||
{ _ten_p11, sizeof (_ten_p11) / sizeof (_ten_p0[11]), 6804, 6800 },
|
||||
{ _ten_p12, sizeof (_ten_p12) / sizeof (_ten_p0[12]), 13607, 13604 }
|
||||
{ _ten_p1, sizeof (_ten_p1) / sizeof (_ten_p1[0]), 7, 4 },
|
||||
{ _ten_p2, sizeof (_ten_p2) / sizeof (_ten_p2[0]), 14, 10 },
|
||||
{ _ten_p3, sizeof (_ten_p3) / sizeof (_ten_p3[0]), 27, 24 },
|
||||
{ _ten_p4, sizeof (_ten_p4) / sizeof (_ten_p4[0]), 54, 50 },
|
||||
{ _ten_p5, sizeof (_ten_p5) / sizeof (_ten_p5[0]), 107, 103 },
|
||||
{ _ten_p6, sizeof (_ten_p6) / sizeof (_ten_p6[0]), 213, 210 },
|
||||
{ _ten_p7, sizeof (_ten_p7) / sizeof (_ten_p7[0]), 426, 422 },
|
||||
{ _ten_p8, sizeof (_ten_p8) / sizeof (_ten_p8[0]), 851, 848 },
|
||||
{ _ten_p9, sizeof (_ten_p9) / sizeof (_ten_p9[0]), 1701, 1698 },
|
||||
{ _ten_p10, sizeof (_ten_p10) / sizeof (_ten_p10[0]), 3402, 3399 },
|
||||
{ _ten_p11, sizeof (_ten_p11) / sizeof (_ten_p11[0]), 6804, 6800 },
|
||||
{ _ten_p12, sizeof (_ten_p12) / sizeof (_ten_p12[0]), 13607, 13604 }
|
||||
};
|
||||
|
||||
#if LDBL_MAX_10_EXP_LOG > LAST_POW10
|
||||
#error "Need to expand 10^(2^i) table for i up to" LDBL_MAX_10_EXP_LOG
|
||||
#if LAST_POW10 > _LAST_POW10
|
||||
#error "Need to expand 10^(2^i) table for i up to" LAST_POW10
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 1995 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -16,7 +16,6 @@ License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#undef atof
|
||||
@ -24,7 +23,8 @@ Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Convert a string to a double. */
|
||||
double
|
||||
DEFUN(atof, (nptr), CONST char *nptr)
|
||||
atof (nptr)
|
||||
const char *nptr;
|
||||
{
|
||||
return(strtod(nptr, (char **) NULL));
|
||||
return __strtod_internal (nptr, (char **) NULL, 0);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 1995 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -16,7 +16,6 @@ License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#undef atoi
|
||||
@ -24,7 +23,8 @@ Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Convert a string to an int. */
|
||||
int
|
||||
DEFUN(atoi, (nptr), CONST char *nptr)
|
||||
atoi (nptr)
|
||||
const char *nptr;
|
||||
{
|
||||
return((int) strtol(nptr, (char **) NULL, 10));
|
||||
return (int) __strtol_internal (nptr, (char **) NULL, 10, 0);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 1995 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -16,7 +16,6 @@ License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ansidecl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#undef atol
|
||||
@ -24,7 +23,8 @@ Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Convert a string to a long int. */
|
||||
long int
|
||||
DEFUN(atol, (nptr), CONST char *nptr)
|
||||
atol (nptr)
|
||||
const char *nptr;
|
||||
{
|
||||
return(strtol(nptr, (char **) NULL, 10));
|
||||
return __strtol_internal (nptr, (char **) NULL, 10, 0);
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ Cambridge, MA 02139, USA. */
|
||||
#define STRTOF strtod
|
||||
#define MPN2FLOAT __mpn_construct_double
|
||||
#define FLOAT_HUGE_VAL HUGE_VAL
|
||||
#define IMPLICIT_ONE 1
|
||||
#endif
|
||||
/* End of configuration part. */
|
||||
|
||||
@ -54,7 +53,6 @@ Cambridge, MA 02139, USA. */
|
||||
#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 MAX_10_EXP_LOG PASTE(FLT,_MAX_10_EXP_LOG)
|
||||
|
||||
/* Extra macros required to get FLT expanded before the pasting. */
|
||||
#define PASTE(a,b) PASTE1(a,b)
|
||||
@ -102,7 +100,7 @@ static const mp_limb _tens_in_limb[MAX_DIG_PER_LIMB + 1] =
|
||||
#define RETURN_LIMB_SIZE howmany (MANT_DIG, BITS_PER_MP_LIMB)
|
||||
|
||||
#define RETURN(val,end) \
|
||||
do { if (endptr != 0) *endptr = (char *) (end); return (val); } while (0)
|
||||
do { if (endptr != 0) *endptr = (char *) (end); return val; } while (0)
|
||||
|
||||
/* Maximum size necessary for mpn integers to hold floating point numbers. */
|
||||
#define MPNSIZE (howmany (MAX_EXP + 2 * MANT_DIG, BITS_PER_MP_LIMB) \
|
||||
@ -120,21 +118,38 @@ static inline FLOAT
|
||||
round_and_return (mp_limb *retval, int exponent, int negative,
|
||||
mp_limb round_limb, mp_size_t round_bit, int more_bits)
|
||||
{
|
||||
if (exponent < MIN_EXP - 2 + IMPLICIT_ONE)
|
||||
if (exponent < MIN_EXP - 1)
|
||||
{
|
||||
mp_size_t shift = MIN_EXP - 2 + IMPLICIT_ONE - exponent;
|
||||
mp_size_t shift = MIN_EXP - 1 - exponent;
|
||||
|
||||
if (shift >= MANT_DIG)
|
||||
if (shift > MANT_DIG)
|
||||
{
|
||||
errno = EDOM;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
more_bits |= (round_limb & ((1 << round_bit) - 1)) != 0;
|
||||
if (shift >= BITS_PER_MP_LIMB)
|
||||
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 = BITS_PER_MP_LIMB - 1;
|
||||
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 & ((1 << round_bit) - 1)) != 0;
|
||||
|
||||
(void) __mpn_rshift (retval, &retval[shift / BITS_PER_MP_LIMB],
|
||||
RETURN_LIMB_SIZE - (shift / BITS_PER_MP_LIMB),
|
||||
@ -167,7 +182,7 @@ round_and_return (mp_limb *retval, int exponent, int negative,
|
||||
retval[RETURN_LIMB_SIZE - 1] |= 1 << ((MANT_DIG - 1)
|
||||
% BITS_PER_MP_LIMB);
|
||||
}
|
||||
else if (IMPLICIT_ONE && exponent == MIN_EXP - 2
|
||||
else if (exponent == MIN_EXP - 2
|
||||
&& (retval[RETURN_LIMB_SIZE - 1]
|
||||
& (1 << ((MANT_DIG - 1) % BITS_PER_MP_LIMB))) != 0)
|
||||
/* The number was denormalized but now normalized. */
|
||||
@ -390,9 +405,13 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
Return current read pointer. */
|
||||
if (!isdigit (c) && c != decimal)
|
||||
{
|
||||
tp = correctly_grouped_prefix (start_of_digits, cp, thousands, grouping);
|
||||
/* If TP is at the start of the digits, there was no correctly
|
||||
grouped prefix of the string; so no number found. */
|
||||
if (grouping)
|
||||
/* Check the grouping of the digits. */
|
||||
tp = correctly_grouped_prefix (start_of_digits, cp, thousands,
|
||||
grouping);
|
||||
else
|
||||
tp = cp;
|
||||
|
||||
RETURN (0.0, tp == start_of_digits ? nptr : tp);
|
||||
}
|
||||
|
||||
@ -418,7 +437,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
/* Check the grouping of the digits. */
|
||||
tp = correctly_grouped_prefix (start_of_digits, cp, thousands, grouping);
|
||||
if (cp != tp)
|
||||
{
|
||||
{
|
||||
/* Less than the entire string was correctly grouped. */
|
||||
|
||||
if (tp == start_of_digits)
|
||||
@ -539,7 +558,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
assert (dig_no >= int_no);
|
||||
}
|
||||
|
||||
number_parsed:
|
||||
number_parsed:
|
||||
|
||||
/* The whole string is parsed. Store the address of the next character. */
|
||||
if (endptr)
|
||||
@ -584,7 +603,6 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
int expbit = 1;
|
||||
const struct mp_power *ttab = &_fpioconst_pow10[0];
|
||||
|
||||
assert (exponent < (1 << (MAX_10_EXP_LOG + 1)));
|
||||
do
|
||||
{
|
||||
if ((exponent & expbit) != 0)
|
||||
|
@ -6,6 +6,5 @@
|
||||
#define STRTOF strtof
|
||||
#define MPN2FLOAT __mpn_construct_float
|
||||
#define FLOAT_HUGE_VAL HUGE_VALf
|
||||
#define IMPLICIT_ONE 1
|
||||
|
||||
#include "strtod.c"
|
||||
|
@ -6,6 +6,5 @@
|
||||
#define STRTOF strtold
|
||||
#define MPN2FLOAT __mpn_construct_long_double
|
||||
#define FLOAT_HUGE_VAL HUGE_VALl
|
||||
#define IMPLICIT_ONE 0 /* XXX for i387 extended format */
|
||||
|
||||
#include "strtod.c"
|
||||
|
Loading…
Reference in New Issue
Block a user