mirror of git://gcc.gnu.org/git/gcc.git
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>
|
2006-04-07 Jerry DeLisle <jvdelisle@gcc.gnu.org>
|
||||||
|
|
||||||
PR libgfortran/26890
|
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
|
Contributed by Andy Vaught
|
||||||
Namelist output contibuted by Paul Thomas
|
Namelist output contibuted by Paul Thomas
|
||||||
|
|
||||||
|
|
@ -376,8 +376,15 @@ calculate_G_format (st_parameter_dt *dtp, const fnode *f,
|
||||||
static void
|
static void
|
||||||
output_float (st_parameter_dt *dtp, const fnode *f, GFC_REAL_LARGEST value)
|
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. */
|
/* This must be large enough to accurately hold any value. */
|
||||||
char buffer[32];
|
char buffer[MIN_FIELD_WIDTH+1];
|
||||||
char *out;
|
char *out;
|
||||||
char *digits;
|
char *digits;
|
||||||
int e;
|
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");
|
internal_error (&dtp->common, "Unspecified precision");
|
||||||
|
|
||||||
/* Use sprintf to print the number in the format +D.DDDDe+ddd
|
/* 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
|
For an N digit exponent, this gives us (MIN_FIELD_WIDTH-5)-N digits
|
||||||
decimal point, plus another one before the decimal point. */
|
after the decimal point, plus another one before the decimal point. */
|
||||||
sign = calculate_sign (dtp, value < 0.0);
|
sign = calculate_sign (dtp, value < 0.0);
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
value = -value;
|
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))
|
|| ((ft == FMT_D || ft == FMT_E) && dtp->u.p.scale_factor != 0))
|
||||||
{
|
{
|
||||||
/* Always convert at full precision to avoid double rounding. */
|
/* Always convert at full precision to avoid double rounding. */
|
||||||
ndigits = 27 - edigits;
|
ndigits = MIN_FIELD_WIDTH - 4 - edigits;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -449,8 +456,8 @@ output_float (st_parameter_dt *dtp, const fnode *f, GFC_REAL_LARGEST value)
|
||||||
ndigits = d + 1;
|
ndigits = d + 1;
|
||||||
else
|
else
|
||||||
ndigits = d;
|
ndigits = d;
|
||||||
if (ndigits > 27 - edigits)
|
if (ndigits > MIN_FIELD_WIDTH - 4 - edigits)
|
||||||
ndigits = 27 - edigits;
|
ndigits = MIN_FIELD_WIDTH - 4 - edigits;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* # The result will always contain a decimal point, even if no
|
/* # 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
|
* + 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
|
* * (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
|
* equal to the precision. The exponent always contains at least two
|
||||||
* digits; if the value is zero, the exponent is 00.
|
* digits; if the value is zero, the exponent is 00.
|
||||||
*/
|
*/
|
||||||
sprintf (buffer, "%+-#31.*" GFC_REAL_LARGEST_FORMAT "e",
|
sprintf (buffer, "%+-#" STR(MIN_FIELD_WIDTH) ".*"
|
||||||
ndigits - 1, value);
|
GFC_REAL_LARGEST_FORMAT "e", ndigits - 1, value);
|
||||||
|
|
||||||
/* Check the resulting string has punctuation in the correct places. */
|
/* Check the resulting string has punctuation in the correct places. */
|
||||||
if (d != 0 && (buffer[2] != '.' || buffer[ndigits + 2] != 'e'))
|
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--;
|
edigits--;
|
||||||
}
|
}
|
||||||
#if HAVE_SNPRINTF
|
#if HAVE_SNPRINTF
|
||||||
snprintf (buffer, 32, "%+0*d", edigits, e);
|
snprintf (buffer, sizeof (buffer), "%+0*d", edigits, e);
|
||||||
#else
|
#else
|
||||||
sprintf (buffer, "%+0*d", edigits, e);
|
sprintf (buffer, "%+0*d", edigits, e);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -790,6 +797,9 @@ output_float (st_parameter_dt *dtp, const fnode *f, GFC_REAL_LARGEST value)
|
||||||
memset( out , ' ' , nblanks );
|
memset( out , ' ' , nblanks );
|
||||||
dtp->u.p.no_leading_blank = 0;
|
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.
|
/* Output a real number with default format.
|
||||||
This is 1PG14.7E2 for REAL(4), 1PG23.15E3 for REAL(8),
|
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
|
static void
|
||||||
write_real (st_parameter_dt *dtp, const char *source, int length)
|
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;
|
f.u.real.e = 4;
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
f.u.real.w = 40;
|
f.u.real.w = 43;
|
||||||
f.u.real.d = 31;
|
f.u.real.d = 34;
|
||||||
f.u.real.e = 4;
|
f.u.real.e = 4;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue