1 /* Copyright (C) 2007-2015 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
3 Write float code factoring to this file by Jerry DeLisle
4 F2003 I/O support contributed by Jerry DeLisle
6 This file is part of the GNU Fortran runtime library (libgfortran).
8 Libgfortran is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 Libgfortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
30 { S_NONE, S_MINUS, S_PLUS }
33 /* Given a flag that indicates if a value is negative or not, return a
34 sign_t that gives the sign that we need to produce. */
37 calculate_sign (st_parameter_dt *dtp, int negative_flag)
44 switch (dtp->u.p.sign_status)
46 case SIGN_SP: /* Show sign. */
49 case SIGN_SS: /* Suppress sign. */
52 case SIGN_S: /* Processor defined. */
53 case SIGN_UNSPECIFIED:
54 s = options.optional_plus ? S_PLUS : S_NONE;
62 /* Determine the precision except for EN format. For G format,
63 determines an upper bound to be used for sizing the buffer. */
66 determine_precision (st_parameter_dt * dtp, const fnode * f, int len)
68 int precision = f->u.real.d;
74 precision += dtp->u.p.scale_factor;
77 /* Scale factor has no effect on output. */
81 /* See F2008 10.7.2.3.3.6 */
82 if (dtp->u.p.scale_factor <= 0)
83 precision += dtp->u.p.scale_factor - 1;
89 /* If the scale factor has a large negative value, we must do our
90 own rounding? Use ROUND='NEAREST', which should be what snprintf
93 (dtp->u.p.current_unit->round_status == ROUND_UNSPECIFIED
94 || dtp->u.p.current_unit->round_status == ROUND_PROCDEFINED))
95 dtp->u.p.current_unit->round_status = ROUND_NEAREST;
97 /* Add extra guard digits up to at least full precision when we do
99 if (dtp->u.p.current_unit->round_status != ROUND_UNSPECIFIED
100 && dtp->u.p.current_unit->round_status != ROUND_PROCDEFINED)
102 precision += 2 * len + 4;
111 /* Output a real number according to its format which is FMT_G free. */
114 output_float (st_parameter_dt *dtp, const fnode *f, char *buffer, size_t size,
115 int nprinted, int precision, int sign_bit, bool zero_flag)
122 /* Number of digits before the decimal point. */
124 /* Number of zeros after the decimal point. */
126 /* Number of digits after the decimal point. */
130 int ndigits, edigits;
136 p = dtp->u.p.scale_factor;
140 /* We should always know the field width and precision. */
142 internal_error (&dtp->common, "Unspecified precision");
144 sign = calculate_sign (dtp, sign_bit);
146 /* Calculate total number of digits. */
148 ndigits = nprinted - 2;
150 ndigits = precision + 1;
152 /* Read the exponent back in. */
154 e = atoi (&buffer[ndigits + 3]) + 1;
158 /* Make sure zero comes out as 0.0e0. */
162 /* Normalize the fractional component. */
165 buffer[2] = buffer[1];
171 /* Figure out where to place the decimal point. */
175 nbefore = ndigits - precision;
176 /* Make sure the decimal point is a '.'; depending on the
177 locale, this might not be the case otherwise. */
178 digits[nbefore] = '.';
184 memmove (digits + nbefore, digits + nbefore + 1, p);
185 digits[nbefore + p] = '.';
195 if (nbefore + p >= 0)
198 memmove (digits + nbefore + p + 1, digits + nbefore + p, -p);
200 digits[nbefore] = '.';
205 nzero = -(nbefore + p);
206 memmove (digits + 1, digits, nbefore);
208 nafter = d + nbefore;
221 while (digits[0] == '0' && nbefore > 0)
229 /* If we need to do rounding ourselves, get rid of the dot by
230 moving the fractional part. */
231 if (dtp->u.p.current_unit->round_status != ROUND_UNSPECIFIED
232 && dtp->u.p.current_unit->round_status != ROUND_PROCDEFINED)
233 memmove (digits + nbefore, digits + nbefore + 1, ndigits - nbefore);
238 i = dtp->u.p.scale_factor;
239 if (d <= 0 && p == 0)
241 generate_error (&dtp->common, LIBERROR_FORMAT, "Precision not "
242 "greater than zero in format specifier 'E' or 'D'");
245 if (p <= -d || p >= d + 2)
247 generate_error (&dtp->common, LIBERROR_FORMAT, "Scale factor "
248 "out of range in format specifier 'E' or 'D'");
264 nafter = (d - p) + 1;
280 /* The exponent must be a multiple of three, with 1-3 digits before
281 the decimal point. */
290 nbefore = 3 - nbefore;
309 /* Should never happen. */
310 internal_error (&dtp->common, "Unexpected format token");
316 /* Round the value. The value being rounded is an unsigned magnitude. */
317 switch (dtp->u.p.current_unit->round_status)
319 /* For processor defined and unspecified rounding we use
320 snprintf to print the exact number of digits needed, and thus
321 let snprintf handle the rounding. On system claiming support
322 for IEEE 754, this ought to be round to nearest, ties to
323 even, corresponding to the Fortran ROUND='NEAREST'. */
324 case ROUND_PROCDEFINED:
325 case ROUND_UNSPECIFIED:
326 case ROUND_ZERO: /* Do nothing and truncation occurs. */
337 /* Round compatible unless there is a tie. A tie is a 5 with
338 all trailing zero's. */
339 i = nafter + nbefore;
340 if (digits[i] == '5')
342 for(i++ ; i < ndigits; i++)
344 if (digits[i] != '0')
347 /* It is a tie so round to even. */
348 switch (digits[nafter + nbefore - 1])
355 /* If odd, round away from zero to even. */
358 /* If even, skip rounding, truncate to even. */
363 /* The ROUND_COMPATIBLE is rounding away from zero when there is a tie. */
364 case ROUND_COMPATIBLE:
372 if (ft != FMT_F && w > 0 && d == 0 && p == 0)
374 /* Scan for trailing zeros to see if we really need to round it. */
375 for(i = nbefore + nafter; i < ndigits; i++)
377 if (digits[i] != '0')
384 if (nbefore + nafter == 0)
385 /* Handle the case Fw.0 and value < 1.0 */
388 if (digits[0] >= rchar)
390 /* We rounded to zero but shouldn't have */
397 else if (nbefore + nafter < ndigits)
399 i = ndigits = nbefore + nafter;
400 if (digits[i] >= rchar)
402 /* Propagate the carry. */
403 for (i--; i >= 0; i--)
405 if (digits[i] != '9')
415 /* The carry overflowed. Fortunately we have some spare
416 space at the start of the buffer. We may discard some
417 digits, but this is ok because we already know they are
431 else if (ft == FMT_EN)
448 /* Calculate the format of the exponent field. */
449 if (expchar && !(dtp->u.p.g0_no_blanks && e == 0))
452 for (i = abs (e); i >= 10; i /= 10)
457 /* Width not specified. Must be no more than 3 digits. */
458 if (e > 999 || e < -999)
463 if (e > 99 || e < -99)
469 /* Exponent width specified, check it is wide enough. */
470 if (edigits > f->u.real.e)
473 edigits = f->u.real.e + 2;
479 /* Scan the digits string and count the number of zeros. If we make it
480 all the way through the loop, we know the value is zero after the
481 rounding completed above. */
483 for (i = 0; i < ndigits + hasdot; i++)
485 if (digits[i] == '.')
487 else if (digits[i] != '0')
491 /* To format properly, we need to know if the rounded result is zero and if
492 so, we set the zero_flag which may have been already set for
494 if (i == ndigits + hasdot)
497 /* The output is zero, so set the sign according to the sign bit unless
498 -fno-sign-zero was specified. */
499 if (compile_options.sign_zero == 1)
500 sign = calculate_sign (dtp, sign_bit);
502 sign = calculate_sign (dtp, 0);
505 /* Pick a field size if none was specified, taking into account small
506 values that may have been rounded to zero. */
510 w = d + (sign != S_NONE ? 2 : 1) + (d == 0 ? 1 : 0);
513 w = nbefore + nzero + nafter + (sign != S_NONE ? 2 : 1);
518 /* Work out how much padding is needed. */
519 nblanks = w - (nbefore + nzero + nafter + edigits + 1);
523 /* See if we have space for a zero before the decimal point. */
524 if (nbefore == 0 && nblanks > 0)
532 if (dtp->u.p.g0_no_blanks)
538 /* Create the ouput buffer. */
539 out = write_block (dtp, w);
543 /* Check the value fits in the specified field width. */
544 if (nblanks < 0 || edigits == -1 || w == 1 || (w == 2 && sign != S_NONE))
546 if (unlikely (is_char4_unit (dtp)))
548 gfc_char4_t *out4 = (gfc_char4_t *) out;
549 memset4 (out4, '*', w);
556 /* For internal character(kind=4) units, we duplicate the code used for
557 regular output slightly modified. This needs to be maintained
558 consistent with the regular code that follows this block. */
559 if (unlikely (is_char4_unit (dtp)))
561 gfc_char4_t *out4 = (gfc_char4_t *) out;
562 /* Pad to full field width. */
564 if ( ( nblanks > 0 ) && !dtp->u.p.no_leading_blank)
566 memset4 (out4, ' ', nblanks);
570 /* Output the initial sign (if any). */
573 else if (sign == S_MINUS)
576 /* Output an optional leading zero. */
580 /* Output the part before the decimal point, padding with zeros. */
583 if (nbefore > ndigits)
586 memcpy4 (out4, digits, i);
594 memcpy4 (out4, digits, i);
602 /* Output the decimal point. */
603 *(out4++) = dtp->u.p.current_unit->decimal_status
604 == DECIMAL_POINT ? '.' : ',';
606 && (dtp->u.p.current_unit->round_status == ROUND_UNSPECIFIED
607 || dtp->u.p.current_unit->round_status == ROUND_PROCDEFINED))
610 /* Output leading zeros after the decimal point. */
613 for (i = 0; i < nzero; i++)
617 /* Output digits after the decimal point, padding with zeros. */
620 if (nafter > ndigits)
625 memcpy4 (out4, digits, i);
634 /* Output the exponent. */
635 if (expchar && !(dtp->u.p.g0_no_blanks && e == 0))
642 snprintf (buffer, size, "%+0*d", edigits, e);
643 memcpy4 (out4, buffer, edigits);
646 if (dtp->u.p.no_leading_blank)
649 memset4 (out4, ' ' , nblanks);
650 dtp->u.p.no_leading_blank = 0;
653 } /* End of character(kind=4) internal unit code. */
655 /* Pad to full field width. */
657 if ( ( nblanks > 0 ) && !dtp->u.p.no_leading_blank)
659 memset (out, ' ', nblanks);
663 /* Output the initial sign (if any). */
666 else if (sign == S_MINUS)
669 /* Output an optional leading zero. */
673 /* Output the part before the decimal point, padding with zeros. */
676 if (nbefore > ndigits)
679 memcpy (out, digits, i);
687 memcpy (out, digits, i);
695 /* Output the decimal point. */
696 *(out++) = dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? '.' : ',';
698 && (dtp->u.p.current_unit->round_status == ROUND_UNSPECIFIED
699 || dtp->u.p.current_unit->round_status == ROUND_PROCDEFINED))
702 /* Output leading zeros after the decimal point. */
705 for (i = 0; i < nzero; i++)
709 /* Output digits after the decimal point, padding with zeros. */
712 if (nafter > ndigits)
717 memcpy (out, digits, i);
726 /* Output the exponent. */
727 if (expchar && !(dtp->u.p.g0_no_blanks && e == 0))
734 snprintf (buffer, size, "%+0*d", edigits, e);
735 memcpy (out, buffer, edigits);
738 if (dtp->u.p.no_leading_blank)
741 memset( out , ' ' , nblanks );
742 dtp->u.p.no_leading_blank = 0;
749 /* Write "Infinite" or "Nan" as appropriate for the given format. */
752 write_infnan (st_parameter_dt *dtp, const fnode *f, int isnan_flag, int sign_bit)
759 if (f->format != FMT_B && f->format != FMT_O && f->format != FMT_Z)
761 sign = calculate_sign (dtp, sign_bit);
762 mark = (sign == S_PLUS || sign == S_MINUS) ? 8 : 7;
766 /* If the field width is zero, the processor must select a width
767 not zero. 4 is chosen to allow output of '-Inf' or '+Inf' */
769 if ((nb == 0) || dtp->u.p.g0_no_blanks)
774 nb = (sign == S_PLUS || sign == S_MINUS) ? 4 : 3;
776 p = write_block (dtp, nb);
781 if (unlikely (is_char4_unit (dtp)))
783 gfc_char4_t *p4 = (gfc_char4_t *) p;
784 memset4 (p4, '*', nb);
791 if (unlikely (is_char4_unit (dtp)))
793 gfc_char4_t *p4 = (gfc_char4_t *) p;
794 memset4 (p4, ' ', nb);
803 /* If the sign is negative and the width is 3, there is
804 insufficient room to output '-Inf', so output asterisks */
807 if (unlikely (is_char4_unit (dtp)))
809 gfc_char4_t *p4 = (gfc_char4_t *) p;
810 memset4 (p4, '*', nb);
816 /* The negative sign is mandatory */
820 /* The positive sign is optional, but we output it for
824 if (unlikely (is_char4_unit (dtp)))
826 gfc_char4_t *p4 = (gfc_char4_t *) p;
829 /* We have room, so output 'Infinity' */
830 memcpy4 (p4 + nb - 8, "Infinity", 8);
832 /* For the case of width equals mark, there is not enough room
833 for the sign and 'Infinity' so we go with 'Inf' */
834 memcpy4 (p4 + nb - 3, "Inf", 3);
836 if (sign == S_PLUS || sign == S_MINUS)
838 if (nb < 9 && nb > 3)
839 /* Put the sign in front of Inf */
840 p4[nb - 4] = (gfc_char4_t) fin;
842 /* Put the sign in front of Infinity */
843 p4[nb - 9] = (gfc_char4_t) fin;
849 /* We have room, so output 'Infinity' */
850 memcpy(p + nb - 8, "Infinity", 8);
852 /* For the case of width equals 8, there is not enough room
853 for the sign and 'Infinity' so we go with 'Inf' */
854 memcpy(p + nb - 3, "Inf", 3);
856 if (sign == S_PLUS || sign == S_MINUS)
858 if (nb < 9 && nb > 3)
859 p[nb - 4] = fin; /* Put the sign in front of Inf */
861 p[nb - 9] = fin; /* Put the sign in front of Infinity */
866 if (unlikely (is_char4_unit (dtp)))
868 gfc_char4_t *p4 = (gfc_char4_t *) p;
869 memcpy4 (p4 + nb - 3, "NaN", 3);
872 memcpy(p + nb - 3, "NaN", 3);
879 /* Returns the value of 10**d. */
881 #define CALCULATE_EXP(x) \
882 static GFC_REAL_ ## x \
883 calculate_exp_ ## x (int d)\
886 GFC_REAL_ ## x r = 1.0;\
887 for (i = 0; i< (d >= 0 ? d : -d); i++)\
889 r = (d >= 0) ? r : 1.0 / r;\
897 #ifdef HAVE_GFC_REAL_10
901 #ifdef HAVE_GFC_REAL_16
907 /* Define a macro to build code for write_float. */
909 /* Note: Before output_float is called, snprintf is used to print to buffer the
910 number in the format +D.DDDDe+ddd.
912 # The result will always contain a decimal point, even if no
915 - The converted value is to be left adjusted on the field boundary
917 + A sign (+ or -) always be placed before a number
919 * prec is used as the precision
921 e format: [-]d.ddde±dd where there is one digit before the
922 decimal-point character and the number of digits after it is
923 equal to the precision. The exponent always contains at least two
924 digits; if the value is zero, the exponent is 00. */
927 #define TOKENPASTE(x, y) TOKENPASTE2(x, y)
928 #define TOKENPASTE2(x, y) x ## y
930 #define DTOA(suff,prec,val) TOKENPASTE(DTOA2,suff)(prec,val)
932 #define DTOA2(prec,val) \
933 snprintf (buffer, size, "%+-#.*e", (prec), (val))
935 #define DTOA2L(prec,val) \
936 snprintf (buffer, size, "%+-#.*Le", (prec), (val))
939 #if defined(GFC_REAL_16_IS_FLOAT128)
940 #define DTOA2Q(prec,val) \
941 quadmath_snprintf (buffer, size, "%+-#.*Qe", (prec), (val))
944 #define FDTOA(suff,prec,val) TOKENPASTE(FDTOA2,suff)(prec,val)
946 /* For F format, we print to the buffer with f format. */
947 #define FDTOA2(prec,val) \
948 snprintf (buffer, size, "%+-#.*f", (prec), (val))
950 #define FDTOA2L(prec,val) \
951 snprintf (buffer, size, "%+-#.*Lf", (prec), (val))
954 #if defined(GFC_REAL_16_IS_FLOAT128)
955 #define FDTOA2Q(prec,val) \
956 quadmath_snprintf (buffer, size, "%+-#.*Qf", \
962 /* Generate corresponding I/O format for FMT_G and output.
963 The rules to translate FMT_G to FMT_E or FMT_F from DEC fortran
964 LRM (table 11-2, Chapter 11, "I/O Formatting", P11-25) is:
966 Data Magnitude Equivalent Conversion
967 0< m < 0.1-0.5*10**(-d-1) Ew.d[Ee]
968 m = 0 F(w-n).(d-1), n' '
969 0.1-0.5*10**(-d-1)<= m < 1-0.5*10**(-d) F(w-n).d, n' '
970 1-0.5*10**(-d)<= m < 10-0.5*10**(-d+1) F(w-n).(d-1), n' '
971 10-0.5*10**(-d+1)<= m < 100-0.5*10**(-d+2) F(w-n).(d-2), n' '
972 ................ ..........
973 10**(d-1)-0.5*10**(-1)<= m <10**d-0.5 F(w-n).0,n(' ')
974 m >= 10**d-0.5 Ew.d[Ee]
976 notes: for Gw.d , n' ' means 4 blanks
977 for Gw.dEe, n' ' means e+2 blanks
978 for rounding modes adjustment, r, See Fortran F2008 10.7.5.2.2
979 the asm volatile is required for 32-bit x86 platforms. */
981 #define OUTPUT_FLOAT_FMT_G(x,y) \
983 output_float_FMT_G_ ## x (st_parameter_dt *dtp, const fnode *f, \
984 GFC_REAL_ ## x m, char *buffer, size_t size, \
985 int sign_bit, bool zero_flag, int comp_d) \
987 int e = f->u.real.e;\
988 int d = f->u.real.d;\
989 int w = f->u.real.w;\
991 GFC_REAL_ ## x exp_d, r = 0.5, r_sc;\
995 int save_scale_factor, nb = 0;\
997 int nprinted, precision;\
998 volatile GFC_REAL_ ## x temp;\
1000 save_scale_factor = dtp->u.p.scale_factor;\
1002 switch (dtp->u.p.current_unit->round_status)\
1005 r = sign_bit ? 1.0 : 0.0;\
1017 exp_d = calculate_exp_ ## x (d);\
1018 r_sc = (1 - r / exp_d);\
1020 if ((m > 0.0 && ((m < temp) || (r >= (exp_d - m))))\
1021 || ((m == 0.0) && !(compile_options.allow_std\
1022 & (GFC_STD_F2003 | GFC_STD_F2008)))\
1025 newf.format = FMT_E;\
1027 newf.u.real.d = d - comp_d;\
1030 precision = determine_precision (dtp, &newf, x);\
1031 nprinted = DTOA(y,precision,m); \
1041 while (low <= high)\
1043 mid = (low + high) / 2;\
1045 temp = (calculate_exp_ ## x (mid - 1) * r_sc);\
1050 if (ubound == lbound + 1)\
1057 if (ubound == lbound + 1)\
1071 nb = e <= 0 ? 4 : e + 2;\
1072 nb = nb >= w ? w - 1 : nb;\
1073 newf.format = FMT_F;\
1074 newf.u.real.w = w - nb;\
1075 newf.u.real.d = m == 0.0 ? d - 1 : -(mid - d - 1) ;\
1076 dtp->u.p.scale_factor = 0;\
1077 precision = determine_precision (dtp, &newf, x); \
1078 nprinted = FDTOA(y,precision,m); \
1081 result = output_float (dtp, &newf, buffer, size, nprinted, precision,\
1082 sign_bit, zero_flag);\
1083 dtp->u.p.scale_factor = save_scale_factor;\
1086 if (nb > 0 && !dtp->u.p.g0_no_blanks)\
1088 p = write_block (dtp, nb);\
1093 if (unlikely (is_char4_unit (dtp)))\
1095 gfc_char4_t *p4 = (gfc_char4_t *) p;\
1096 memset4 (p4, pad, nb);\
1099 memset (p, pad, nb);\
1103 OUTPUT_FLOAT_FMT_G(4,)
1105 OUTPUT_FLOAT_FMT_G(8,)
1107 #ifdef HAVE_GFC_REAL_10
1108 OUTPUT_FLOAT_FMT_G(10,L)
1111 #ifdef HAVE_GFC_REAL_16
1112 # ifdef GFC_REAL_16_IS_FLOAT128
1113 OUTPUT_FLOAT_FMT_G(16,Q)
1115 OUTPUT_FLOAT_FMT_G(16,L)
1119 #undef OUTPUT_FLOAT_FMT_G
1122 /* EN format is tricky since the number of significant digits depends
1123 on the magnitude. Solve it by first printing a temporary value and
1124 figure out the number of significant digits from the printed
1125 exponent. Values y, 0.95*10.0**e <= y <10.0**e, are rounded to
1126 10.0**e even when the final result will not be rounded to 10.0**e.
1127 For these values the exponent returned by atoi has to be decremented
1128 by one. The values y in the ranges
1129 (1000.0-0.5*10.0**(-d))*10.0**(3*n) <= y < 10.0*(3*(n+1))
1130 (100.0-0.5*10.0**(-d))*10.0**(3*n) <= y < 10.0*(3*n+2)
1131 (10.0-0.5*10.0**(-d))*10.0**(3*n) <= y < 10.0*(3*n+1)
1132 are correctly rounded respectively to 1.0...0*10.0*(3*(n+1)),
1133 100.0...0*10.0*(3*n), and 10.0...0*10.0*(3*n), where 0...0
1134 represents d zeroes, by the lines 279 to 297. */
1136 #define EN_PREC(x,y)\
1138 volatile GFC_REAL_ ## x tmp, one = 1.0;\
1139 tmp = * (GFC_REAL_ ## x *)source;\
1140 if (isfinite (tmp))\
1142 nprinted = DTOA(y,0,tmp);\
1143 int e = atoi (&buffer[4]);\
1144 if (buffer[1] == '1')\
1146 tmp = (calculate_exp_ ## x (-e)) * tmp;\
1147 tmp = one - (tmp < 0 ? -tmp : tmp); \
1153 nbefore = 3 + nbefore;\
1160 determine_en_precision (st_parameter_dt *dtp, const fnode *f,
1161 const char *source, int len)
1165 const size_t size = 10;
1166 int nbefore; /* digits before decimal point - 1. */
1178 #ifdef HAVE_GFC_REAL_10
1183 #ifdef HAVE_GFC_REAL_16
1185 # ifdef GFC_REAL_16_IS_FLOAT128
1193 internal_error (NULL, "bad real kind");
1199 int prec = f->u.real.d + nbefore;
1200 if (dtp->u.p.current_unit->round_status != ROUND_UNSPECIFIED
1201 && dtp->u.p.current_unit->round_status != ROUND_PROCDEFINED)
1202 prec += 2 * len + 4;
1207 #define WRITE_FLOAT(x,y)\
1209 GFC_REAL_ ## x tmp;\
1210 tmp = * (GFC_REAL_ ## x *)source;\
1211 sign_bit = signbit (tmp);\
1212 if (!isfinite (tmp))\
1214 write_infnan (dtp, f, isnan (tmp), sign_bit);\
1217 tmp = sign_bit ? -tmp : tmp;\
1218 zero_flag = (tmp == 0.0);\
1219 if (f->format == FMT_G)\
1220 output_float_FMT_G_ ## x (dtp, f, tmp, buffer, size, sign_bit, \
1221 zero_flag, comp_d);\
1224 if (f->format == FMT_F)\
1225 nprinted = FDTOA(y,precision,tmp); \
1227 nprinted = DTOA(y,precision,tmp); \
1228 output_float (dtp, f, buffer, size, nprinted, precision,\
1229 sign_bit, zero_flag);\
1233 /* Output a real number according to its format. */
1236 write_float (st_parameter_dt *dtp, const fnode *f, const char *source, \
1237 int len, int comp_d)
1239 int sign_bit, nprinted;
1240 int precision; /* Precision for snprintf call. */
1243 if (f->format != FMT_EN)
1244 precision = determine_precision (dtp, f, len);
1246 precision = determine_en_precision (dtp, f, source, len);
1248 /* 4932 is the maximum exponent of long double and quad precision, 3
1249 extra characters for the sign, the decimal point, and the
1250 trailing null, and finally some extra digits depending on the
1251 requested precision. */
1252 const size_t size = 4932 + 3 + precision;
1253 #define BUF_STACK_SZ 5000
1254 char buf_stack[BUF_STACK_SZ];
1256 if (size > BUF_STACK_SZ)
1257 buffer = xmalloc (size);
1271 #ifdef HAVE_GFC_REAL_10
1276 #ifdef HAVE_GFC_REAL_16
1278 # ifdef GFC_REAL_16_IS_FLOAT128
1286 internal_error (NULL, "bad real kind");
1288 if (size > BUF_STACK_SZ)