re PR libfortran/24685 (real(16) formatted input is broken for huge values (gfortran.dg/default_format_2.f90))
PR libgfortran/24685 * io/write.c (MIN_FIELD_WIDTH, STR, STR1): Define. (output_float): Increase buffer sizes for IEEE quad and IBM extended long double. (write_real): Output REAL(16) as 1PG43.34E4 rather than 1PG40.31E4. From-SVN: r112819
This commit is contained in:
parent
9f889fcf52
commit
55fc9243b7
@ -1,3 +1,11 @@
|
||||
2006-04-10 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR libgfortran/24685
|
||||
* io/write.c (MIN_FIELD_WIDTH, STR, STR1): Define.
|
||||
(output_float): Increase buffer sizes for IEEE quad and IBM extended
|
||||
long double.
|
||||
(write_real): Output REAL(16) as 1PG43.34E4 rather than 1PG40.31E4.
|
||||
|
||||
2006-04-07 Jerry DeLisle <jvdelisle@gcc.gnu.org>
|
||||
|
||||
PR libgfortran/26890
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
Contributed by Andy Vaught
|
||||
Namelist output contibuted by Paul Thomas
|
||||
|
||||
@ -376,8 +376,15 @@ calculate_G_format (st_parameter_dt *dtp, const fnode *f,
|
||||
static void
|
||||
output_float (st_parameter_dt *dtp, const fnode *f, GFC_REAL_LARGEST value)
|
||||
{
|
||||
#if defined(HAVE_GFC_REAL_16) && __LDBL_DIG__ > 18
|
||||
# define MIN_FIELD_WIDTH 46
|
||||
#else
|
||||
# define MIN_FIELD_WIDTH 31
|
||||
#endif
|
||||
#define STR(x) STR1(x)
|
||||
#define STR1(x) #x
|
||||
/* This must be large enough to accurately hold any value. */
|
||||
char buffer[32];
|
||||
char buffer[MIN_FIELD_WIDTH+1];
|
||||
char *out;
|
||||
char *digits;
|
||||
int e;
|
||||
@ -413,8 +420,8 @@ output_float (st_parameter_dt *dtp, const fnode *f, GFC_REAL_LARGEST value)
|
||||
internal_error (&dtp->common, "Unspecified precision");
|
||||
|
||||
/* Use sprintf to print the number in the format +D.DDDDe+ddd
|
||||
For an N digit exponent, this gives us (32-6)-N digits after the
|
||||
decimal point, plus another one before the decimal point. */
|
||||
For an N digit exponent, this gives us (MIN_FIELD_WIDTH-5)-N digits
|
||||
after the decimal point, plus another one before the decimal point. */
|
||||
sign = calculate_sign (dtp, value < 0.0);
|
||||
if (value < 0)
|
||||
value = -value;
|
||||
@ -439,7 +446,7 @@ output_float (st_parameter_dt *dtp, const fnode *f, GFC_REAL_LARGEST value)
|
||||
|| ((ft == FMT_D || ft == FMT_E) && dtp->u.p.scale_factor != 0))
|
||||
{
|
||||
/* Always convert at full precision to avoid double rounding. */
|
||||
ndigits = 27 - edigits;
|
||||
ndigits = MIN_FIELD_WIDTH - 4 - edigits;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -449,8 +456,8 @@ output_float (st_parameter_dt *dtp, const fnode *f, GFC_REAL_LARGEST value)
|
||||
ndigits = d + 1;
|
||||
else
|
||||
ndigits = d;
|
||||
if (ndigits > 27 - edigits)
|
||||
ndigits = 27 - edigits;
|
||||
if (ndigits > MIN_FIELD_WIDTH - 4 - edigits)
|
||||
ndigits = MIN_FIELD_WIDTH - 4 - edigits;
|
||||
}
|
||||
|
||||
/* # The result will always contain a decimal point, even if no
|
||||
@ -460,7 +467,7 @@ output_float (st_parameter_dt *dtp, const fnode *f, GFC_REAL_LARGEST value)
|
||||
*
|
||||
* + A sign (+ or -) always be placed before a number
|
||||
*
|
||||
* 31 minimum field width
|
||||
* MIN_FIELD_WIDTH minimum field width
|
||||
*
|
||||
* * (ndigits-1) is used as the precision
|
||||
*
|
||||
@ -469,8 +476,8 @@ output_float (st_parameter_dt *dtp, const fnode *f, GFC_REAL_LARGEST value)
|
||||
* equal to the precision. The exponent always contains at least two
|
||||
* digits; if the value is zero, the exponent is 00.
|
||||
*/
|
||||
sprintf (buffer, "%+-#31.*" GFC_REAL_LARGEST_FORMAT "e",
|
||||
ndigits - 1, value);
|
||||
sprintf (buffer, "%+-#" STR(MIN_FIELD_WIDTH) ".*"
|
||||
GFC_REAL_LARGEST_FORMAT "e", ndigits - 1, value);
|
||||
|
||||
/* Check the resulting string has punctuation in the correct places. */
|
||||
if (d != 0 && (buffer[2] != '.' || buffer[ndigits + 2] != 'e'))
|
||||
@ -777,7 +784,7 @@ output_float (st_parameter_dt *dtp, const fnode *f, GFC_REAL_LARGEST value)
|
||||
edigits--;
|
||||
}
|
||||
#if HAVE_SNPRINTF
|
||||
snprintf (buffer, 32, "%+0*d", edigits, e);
|
||||
snprintf (buffer, sizeof (buffer), "%+0*d", edigits, e);
|
||||
#else
|
||||
sprintf (buffer, "%+0*d", edigits, e);
|
||||
#endif
|
||||
@ -790,6 +797,9 @@ output_float (st_parameter_dt *dtp, const fnode *f, GFC_REAL_LARGEST value)
|
||||
memset( out , ' ' , nblanks );
|
||||
dtp->u.p.no_leading_blank = 0;
|
||||
}
|
||||
#undef STR
|
||||
#undef STR1
|
||||
#undef MIN_FIELD_WIDTH
|
||||
}
|
||||
|
||||
|
||||
@ -1352,7 +1362,7 @@ write_character (st_parameter_dt *dtp, const char *source, int length)
|
||||
|
||||
/* Output a real number with default format.
|
||||
This is 1PG14.7E2 for REAL(4), 1PG23.15E3 for REAL(8),
|
||||
1PG24.15E4 for REAL(10) and 1PG40.31E4 for REAL(16). */
|
||||
1PG28.19E4 for REAL(10) and 1PG43.34E4 for REAL(16). */
|
||||
|
||||
static void
|
||||
write_real (st_parameter_dt *dtp, const char *source, int length)
|
||||
@ -1379,8 +1389,8 @@ write_real (st_parameter_dt *dtp, const char *source, int length)
|
||||
f.u.real.e = 4;
|
||||
break;
|
||||
case 16:
|
||||
f.u.real.w = 40;
|
||||
f.u.real.d = 31;
|
||||
f.u.real.w = 43;
|
||||
f.u.real.d = 34;
|
||||
f.u.real.e = 4;
|
||||
break;
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user