Fix formatting of denormal IBM long double numbers

This commit is contained in:
Andreas Schwab 2012-04-03 18:38:46 +02:00
parent 6d5c57fabd
commit 7e0d315da8
5 changed files with 115 additions and 16 deletions

View file

@ -1,5 +1,12 @@
2012-04-28 Andreas Schwab <schwab@linux-m68k.org>
[BZ #13941]
* sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c
(__mpn_extract_long_double): Use DBL_MIN_EXP instead of
LDBL_MIN_EXP.
* stdio-common/Makefile (tests): Add tst-sprintf3.
* stdio-common/tst-sprintf3.c: New file.
* elf/Makefile ($(objpfx)tst-leaks1-mem, $(objpfx)noload-mem)
($(objpfx)tst-unused-dep.out): Don't run when cross-compiling.

18
NEWS
View file

@ -13,15 +13,15 @@ Version 2.16
2554, 2562, 2563, 2565, 2566, 2576, 2636, 2678, 3335, 3768, 3866, 3868,
3976, 3992, 4026, 4108, 4596, 4822, 5077, 5461, 5805, 5993, 6471, 6486,
6578, 6649, 6730, 6770, 6794, 6884, 6890, 6894, 6895, 6907, 6911, 7064,
9739, 9902, 10110, 10135, 10140, 10153, 10210, 10254, 10346, 10545,
10716, 11174, 11322, 11365, 11451, 11494, 11521, 11959, 12047, 12340,
13058, 13525, 13526, 13527, 13528, 13529, 13530, 13531, 13532, 13533,
13547, 13551, 13552, 13553, 13555, 13559, 13566, 13583, 13592, 13618,
13637, 13656, 13658, 13673, 13691, 13695, 13704, 13705, 13706, 13726,
13738, 13739, 13760, 13761, 13786, 13792, 13806, 13824, 13840, 13841,
13844, 13846, 13851, 13852, 13854, 13871, 13872, 13873, 13879, 13883,
13886, 13892, 13895, 13908, 13910, 13911, 13912, 13913, 13915, 13916,
13917, 13918, 13919, 13920, 13921, 13926, 13927, 13928, 13938, 13963,
9739, 9902, 10110, 10135, 10140, 10153, 10210, 10254, 10346, 10545, 10716,
11174, 11322, 11365, 11451, 11494, 11521, 11959, 12047, 12340, 13058,
13525, 13526, 13527, 13528, 13529, 13530, 13531, 13532, 13533, 13547,
13551, 13552, 13553, 13555, 13559, 13566, 13583, 13592, 13618, 13637,
13656, 13658, 13673, 13691, 13695, 13704, 13705, 13706, 13726, 13738,
13739, 13760, 13761, 13786, 13792, 13806, 13824, 13840, 13841, 13844,
13846, 13851, 13852, 13854, 13871, 13872, 13873, 13879, 13883, 13886,
13892, 13895, 13908, 13910, 13911, 13912, 13913, 13915, 13916, 13917,
13918, 13919, 13920, 13921, 13926, 13927, 13928, 13938, 13941, 13963,
13967, 13970, 13973, 14027
* ISO C11 support:

View file

@ -56,7 +56,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 bug18 bug18a \
bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22 \
scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24 \
bug-vfprintf-nargs tst-long-dbl-fphex tst-fphex-wide
bug-vfprintf-nargs tst-long-dbl-fphex tst-fphex-wide tst-sprintf3
test-srcs = tst-unbputc tst-printf

View file

@ -0,0 +1,90 @@
/* Copyright (C) 2012 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
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* Test bug #13941. */
#include <float.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
int
main (void)
{
#if LDBL_MANT_DIG >= 106
volatile union { long double l; long long x[2]; } u, v;
char buf[64];
#endif
int result = 0;
#if LDBL_MANT_DIG == 106 || LDBL_MANT_DIG == 113
# define COMPARE_LDBL(u, v) \
((u).l == (v).l && (u).x[0] == (v).x[0] && (u).x[1] == (v).x[1])
#else
# define COMPARE_LDBL(u, v) ((u).l == (v).l)
#endif
#define TEST(val) \
do \
{ \
u.l = (val); \
snprintf (buf, sizeof buf, "%.30LgL", u.l); \
if (strcmp (buf, #val) != 0) \
{ \
printf ("Error on line %d: %s != %s\n", __LINE__, buf, #val); \
result = 1; \
} \
if (sscanf (#val, "%Lg", &v.l) != 1 || !COMPARE_LDBL (u, v)) \
{ \
printf ("Error sscanf on line %d: %.30Lg != %.30Lg\n", __LINE__, \
u.l, v.l); \
result = 1; \
} \
/* printf ("%s %Lg %016Lx %016Lx\n", #val, u.l, u.x[0], u.x[1]); */ \
} \
while (0)
#if LDBL_MANT_DIG >= 106
# if LDBL_MANT_DIG == 106
TEST (2.22507385850719347803989925739e-308L);
TEST (2.22507385850719397210554509863e-308L);
TEST (2.22507385850720088902458687609e-308L);
# endif
TEST (2.22507385850720138309023271733e-308L);
TEST (2.22507385850720187715587855858e-308L);
TEST (2.2250738585074419930597574044e-308L);
TEST (4.45014771701440227211481959342e-308L);
TEST (4.45014771701440276618046543466e-308L);
TEST (4.45014771701440375431175711716e-308L);
TEST (4.45014771701440474244304879965e-308L);
TEST (7.12023634722304600689881138745e-307L);
TEST (1.13923781555569064960474854133e-305L);
TEST (1.13777777777777776389998996996L);
TEST (1.13777777777777765287768750745L);
TEST (20988295479420645138.2044444444L);
TEST (20988295479420643090.2044444444L);
TEST (2.14668699894294423266045294316e-292L);
# if LDBL_MANT_DIG == 106
TEST (-2.35993711055432139266626434123e-292L);
TEST (6.26323524637968345414769634658e-302L);
TEST (1.49327164802066885331814201989e-308L);
TEST (3.71834550652787023640837473722e-308L);
TEST (9.51896449671134907001349268087e-306L);
# endif
#endif
return result;
}

View file

@ -1,5 +1,4 @@
/* Copyright (C) 1995,1996,1997,1998,1999,2002,2003,2006
Free Software Foundation, Inc.
/* Copyright (C) 1995-2012 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
@ -104,7 +103,10 @@ __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
else
{
/* It is a denormal number, meaning it has no implicit leading
one bit, and its exponent is in fact the format minimum. */
one bit, and its exponent is in fact the format minimum. We
use DBL_MIN_EXP instead of LDBL_MIN_EXP below because the
latter describes the properties of both parts together, but
the exponent is computed from the high part only. */
int cnt;
#if N == 2
@ -115,7 +117,7 @@ __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
res_ptr[N - 1] = res_ptr[N - 1] << cnt
| (res_ptr[0] >> (BITS_PER_MP_LIMB - cnt));
res_ptr[0] <<= cnt;
*expt = LDBL_MIN_EXP - 1 - cnt;
*expt = DBL_MIN_EXP - 1 - cnt;
}
else
{
@ -130,7 +132,7 @@ __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
res_ptr[N - 1] = res_ptr[0] >> (NUM_LEADING_ZEROS - cnt);
res_ptr[0] <<= BITS_PER_MP_LIMB - (NUM_LEADING_ZEROS - cnt);
}
*expt = LDBL_MIN_EXP - 1
*expt = DBL_MIN_EXP - 1
- (BITS_PER_MP_LIMB - NUM_LEADING_ZEROS) - cnt;
}
#else
@ -161,7 +163,7 @@ __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
for (; k >= 0; k--)
res_ptr[k] = 0;
*expt = LDBL_MIN_EXP - 1 - l * BITS_PER_MP_LIMB - cnt;
*expt = DBL_MIN_EXP - 1 - l * BITS_PER_MP_LIMB - cnt;
#endif
}
}