diff options
author | Ulrich Drepper <drepper@redhat.com> | 2004-12-22 19:55:46 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2004-12-22 19:55:46 +0000 |
commit | ec8c29dc013a5e0ca3330ce5e4ae989e811491e6 (patch) | |
tree | 89ed45fb997421e63457013f492fa91e5b6abb6c | |
parent | 3b7a95fb6b12e8184299378082831d52381a189b (diff) | |
download | glibc-ec8c29dc013a5e0ca3330ce5e4ae989e811491e6.zip glibc-ec8c29dc013a5e0ca3330ce5e4ae989e811491e6.tar.gz glibc-ec8c29dc013a5e0ca3330ce5e4ae989e811491e6.tar.bz2 |
(FLOAT_MIN_10_EXP, FLOAT_MIN_10_NORM): Define. (ecvt_r): Special case denormals.
-rw-r--r-- | misc/efgcvt_r.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/misc/efgcvt_r.c b/misc/efgcvt_r.c index ac2a5c4..69cca90 100644 --- a/misc/efgcvt_r.c +++ b/misc/efgcvt_r.c @@ -1,5 +1,5 @@ /* Compatibility functions for floating point formatting, reentrant versions. - Copyright (C) 1995,96,97,98,99,2000,01,02 Free Software Foundation, Inc. + Copyright (C) 1995,96,97,98,99,2000,01,02,04 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 @@ -31,6 +31,7 @@ # define FUNC_PREFIX # define FLOAT_FMT_FLAG # define FLOAT_NAME_EXT +# define FLOAT_MIN_10_EXP DBL_MIN_10_EXP # if DBL_MANT_DIG == 53 # define NDIGIT_MAX 17 # elif DBL_MANT_DIG == 24 @@ -43,6 +44,17 @@ # error "NDIGIT_MAX must be precomputed" # define NDIGIT_MAX (lrint (ceil (M_LN2 / M_LN10 * DBL_MANT_DIG + 1.0))) # endif +# if DBL_MIN_10_EXP == -37 +# define FLOAT_MIN_10_NORM 1.0e-37 +# elif DBL_MIN_10_EXP == -307 +# define FLOAT_MIN_10_NORM 1.0e-307 +# elif DBL_MIN_10_EXP == -4931 +# define FLOAT_MIN_10_NORM 1.0e-4931 +# else +/* libc can't depend on libm. */ +# error "FLOAT_MIN_10_NORM must be precomputed" +# define FLOAT_MIN_10_NORM exp10 (DBL_MIN_10_EXP) +# endif #endif #define APPEND(a, b) APPEND2 (a, b) @@ -171,6 +183,17 @@ APPEND (FUNC_PREFIX, ecvt_r) (value, ndigit, decpt, sign, buf, len) d = -value; else d = value; + /* For denormalized numbers the d < 1.0 case below won't work, + as f can overflow to +Inf. */ + if (d < FLOAT_MIN_10_NORM) + { + value /= FLOAT_MIN_10_NORM; + if (value < 0.0) + d = -value; + else + d = value; + exponent += FLOAT_MIN_10_EXP; + } if (d < 1.0) { do |