1 /* Copyright (C) 2007-2014 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. */
128 /* Number of zeros after the decimal point, whatever the precision. */
132 int ndigits, edigits;
138 p = dtp->u.p.scale_factor;
143 /* We should always know the field width and precision. */
145 internal_error (&dtp->common, "Unspecified precision");
147 sign = calculate_sign (dtp, sign_bit);
149 /* Calculate total number of digits. */
151 ndigits = nprinted - 2;
153 ndigits = precision + 1;
155 /* Read the exponent back in. */
157 e = atoi (&buffer[ndigits + 3]) + 1;
161 /* Make sure zero comes out as 0.0e0. */
165 /* Normalize the fractional component. */
168 buffer[2] = buffer[1];
174 /* Figure out where to place the decimal point. */
178 nbefore = ndigits - precision;
179 /* Make sure the decimal point is a '.'; depending on the
180 locale, this might not be the case otherwise. */
181 digits[nbefore] = '.';
187 memmove (digits + nbefore, digits + nbefore + 1, p);
188 digits[nbefore + p] = '.';
194 nzero = nzero_real = 0;
198 if (nbefore + p >= 0)
201 memmove (digits + nbefore + p + 1, digits + nbefore + p, -p);
203 digits[nbefore] = '.';
208 nzero = -(nbefore + p);
209 memmove (digits + 1, digits, nbefore);
211 nafter = d + nbefore;
221 nzero = nzero_real = 0;
225 while (digits[0] == '0' && nbefore > 0)
233 /* If we need to do rounding ourselves, get rid of the dot by
234 moving the fractional part. */
235 if (dtp->u.p.current_unit->round_status != ROUND_UNSPECIFIED
236 && dtp->u.p.current_unit->round_status != ROUND_PROCDEFINED)
237 memmove (digits + nbefore, digits + nbefore + 1, ndigits - nbefore);
242 i = dtp->u.p.scale_factor;
243 if (d <= 0 && p == 0)
245 generate_error (&dtp->common, LIBERROR_FORMAT, "Precision not "
246 "greater than zero in format specifier 'E' or 'D'");
249 if (p <= -d || p >= d + 2)
251 generate_error (&dtp->common, LIBERROR_FORMAT, "Scale factor "
252 "out of range in format specifier 'E' or 'D'");
268 nafter = (d - p) + 1;
284 /* The exponent must be a multiple of three, with 1-3 digits before
285 the decimal point. */
294 nbefore = 3 - nbefore;
313 /* Should never happen. */
314 internal_error (&dtp->common, "Unexpected format token");
320 /* Round the value. The value being rounded is an unsigned magnitude. */
321 switch (dtp->u.p.current_unit->round_status)
323 /* For processor defined and unspecified rounding we use
324 snprintf to print the exact number of digits needed, and thus
325 let snprintf handle the rounding. On system claiming support
326 for IEEE 754, this ought to be round to nearest, ties to
327 even, corresponding to the Fortran ROUND='NEAREST'. */
328 case ROUND_PROCDEFINED:
329 case ROUND_UNSPECIFIED:
330 case ROUND_ZERO: /* Do nothing and truncation occurs. */
341 /* Round compatible unless there is a tie. A tie is a 5 with
342 all trailing zero's. */
343 i = nafter + nbefore;
344 if (digits[i] == '5')
346 for(i++ ; i < ndigits; i++)
348 if (digits[i] != '0')
351 /* It is a tie so round to even. */
352 switch (digits[nafter + nbefore - 1])
359 /* If odd, round away from zero to even. */
362 /* If even, skip rounding, truncate to even. */
367 /* The ROUND_COMPATIBLE is rounding away from zero when there is a tie. */
368 case ROUND_COMPATIBLE:
376 if (ft != FMT_F && nbefore == 0 && w > 0 && d == 0 && p == 0)
378 /* Scan for trailing zeros to see if we really need to round it. */
379 for(i = nbefore + nafter; i < ndigits; i++)
381 if (digits[i] != '0')
388 if (nbefore + nafter == 0)
389 /* Handle the case Fw.0 and value < 1.0 */
392 if (nzero_real == d && digits[0] >= rchar)
394 /* We rounded to zero but shouldn't have */
401 else if (nbefore + nafter < ndigits)
403 i = ndigits = nbefore + nafter;
404 if (digits[i] >= rchar)
406 /* Propagate the carry. */
407 for (i--; i >= 0; i--)
409 if (digits[i] != '9')
419 /* The carry overflowed. Fortunately we have some spare
420 space at the start of the buffer. We may discard some
421 digits, but this is ok because we already know they are
435 else if (ft == FMT_EN)
452 /* Calculate the format of the exponent field. */
456 for (i = abs (e); i >= 10; i /= 10)
461 /* Width not specified. Must be no more than 3 digits. */
462 if (e > 999 || e < -999)
467 if (e > 99 || e < -99)
473 /* Exponent width specified, check it is wide enough. */
474 if (edigits > f->u.real.e)
477 edigits = f->u.real.e + 2;
483 /* Scan the digits string and count the number of zeros. If we make it
484 all the way through the loop, we know the value is zero after the
485 rounding completed above. */
487 for (i = 0; i < ndigits + hasdot; i++)
489 if (digits[i] == '.')
491 else if (digits[i] != '0')
495 /* To format properly, we need to know if the rounded result is zero and if
496 so, we set the zero_flag which may have been already set for
498 if (i == ndigits + hasdot)
501 /* The output is zero, so set the sign according to the sign bit unless
502 -fno-sign-zero was specified. */
503 if (compile_options.sign_zero == 1)
504 sign = calculate_sign (dtp, sign_bit);
506 sign = calculate_sign (dtp, 0);
509 /* Pick a field size if none was specified, taking into account small
510 values that may have been rounded to zero. */
514 w = d + (sign != S_NONE ? 2 : 1) + (d == 0 ? 1 : 0);
517 w = nbefore + nzero + nafter + (sign != S_NONE ? 2 : 1);
522 /* Work out how much padding is needed. */
523 nblanks = w - (nbefore + nzero + nafter + edigits + 1);
527 if (dtp->u.p.g0_no_blanks)
533 /* Create the ouput buffer. */
534 out = write_block (dtp, w);
538 /* Check the value fits in the specified field width. */
539 if (nblanks < 0 || edigits == -1 || w == 1 || (w == 2 && sign != S_NONE))
541 if (unlikely (is_char4_unit (dtp)))
543 gfc_char4_t *out4 = (gfc_char4_t *) out;
544 memset4 (out4, '*', w);
551 /* See if we have space for a zero before the decimal point. */
552 if (nbefore == 0 && nblanks > 0)
560 /* For internal character(kind=4) units, we duplicate the code used for
561 regular output slightly modified. This needs to be maintained
562 consistent with the regular code that follows this block. */
563 if (unlikely (is_char4_unit (dtp)))
565 gfc_char4_t *out4 = (gfc_char4_t *) out;
566 /* Pad to full field width. */
568 if ( ( nblanks > 0 ) && !dtp->u.p.no_leading_blank)
570 memset4 (out4, ' ', nblanks);
574 /* Output the initial sign (if any). */
577 else if (sign == S_MINUS)
580 /* Output an optional leading zero. */
584 /* Output the part before the decimal point, padding with zeros. */
587 if (nbefore > ndigits)
590 memcpy4 (out4, digits, i);
598 memcpy4 (out4, digits, i);
606 /* Output the decimal point. */
607 *(out4++) = dtp->u.p.current_unit->decimal_status
608 == DECIMAL_POINT ? '.' : ',';
610 && (dtp->u.p.current_unit->round_status == ROUND_UNSPECIFIED
611 || dtp->u.p.current_unit->round_status == ROUND_PROCDEFINED))
614 /* Output leading zeros after the decimal point. */
617 for (i = 0; i < nzero; i++)
621 /* Output digits after the decimal point, padding with zeros. */
624 if (nafter > ndigits)
629 memcpy4 (out4, digits, i);
638 /* Output the exponent. */
646 snprintf (buffer, size, "%+0*d", edigits, e);
647 memcpy4 (out4, buffer, edigits);
650 if (dtp->u.p.no_leading_blank)
653 memset4 (out4, ' ' , nblanks);
654 dtp->u.p.no_leading_blank = 0;
657 } /* End of character(kind=4) internal unit code. */
659 /* Pad to full field width. */
661 if ( ( nblanks > 0 ) && !dtp->u.p.no_leading_blank)
663 memset (out, ' ', nblanks);
667 /* Output the initial sign (if any). */
670 else if (sign == S_MINUS)
673 /* Output an optional leading zero. */
677 /* Output the part before the decimal point, padding with zeros. */
680 if (nbefore > ndigits)
683 memcpy (out, digits, i);
691 memcpy (out, digits, i);
699 /* Output the decimal point. */
700 *(out++) = dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? '.' : ',';
702 && (dtp->u.p.current_unit->round_status == ROUND_UNSPECIFIED
703 || dtp->u.p.current_unit->round_status == ROUND_PROCDEFINED))
706 /* Output leading zeros after the decimal point. */
709 for (i = 0; i < nzero; i++)
713 /* Output digits after the decimal point, padding with zeros. */
716 if (nafter > ndigits)
721 memcpy (out, digits, i);
730 /* Output the exponent. */
738 snprintf (buffer, size, "%+0*d", edigits, e);
739 memcpy (out, buffer, edigits);
742 if (dtp->u.p.no_leading_blank)
745 memset( out , ' ' , nblanks );
746 dtp->u.p.no_leading_blank = 0;
753 /* Write "Infinite" or "Nan" as appropriate for the given format. */
756 write_infnan (st_parameter_dt *dtp, const fnode *f, int isnan_flag, int sign_bit)
763 if (f->format != FMT_B && f->format != FMT_O && f->format != FMT_Z)
765 sign = calculate_sign (dtp, sign_bit);
766 mark = (sign == S_PLUS || sign == S_MINUS) ? 8 : 7;
770 /* If the field width is zero, the processor must select a width
771 not zero. 4 is chosen to allow output of '-Inf' or '+Inf' */
773 if ((nb == 0) || dtp->u.p.g0_no_blanks)
778 nb = (sign == S_PLUS || sign == S_MINUS) ? 4 : 3;
780 p = write_block (dtp, nb);
785 if (unlikely (is_char4_unit (dtp)))
787 gfc_char4_t *p4 = (gfc_char4_t *) p;
788 memset4 (p4, '*', nb);
795 if (unlikely (is_char4_unit (dtp)))
797 gfc_char4_t *p4 = (gfc_char4_t *) p;
798 memset4 (p4, ' ', nb);
807 /* If the sign is negative and the width is 3, there is
808 insufficient room to output '-Inf', so output asterisks */
811 if (unlikely (is_char4_unit (dtp)))
813 gfc_char4_t *p4 = (gfc_char4_t *) p;
814 memset4 (p4, '*', nb);
820 /* The negative sign is mandatory */
824 /* The positive sign is optional, but we output it for
828 if (unlikely (is_char4_unit (dtp)))
830 gfc_char4_t *p4 = (gfc_char4_t *) p;
833 /* We have room, so output 'Infinity' */
834 memcpy4 (p4 + nb - 8, "Infinity", 8);
836 /* For the case of width equals mark, there is not enough room
837 for the sign and 'Infinity' so we go with 'Inf' */
838 memcpy4 (p4 + nb - 3, "Inf", 3);
840 if (sign == S_PLUS || sign == S_MINUS)
842 if (nb < 9 && nb > 3)
843 /* Put the sign in front of Inf */
844 p4[nb - 4] = (gfc_char4_t) fin;
846 /* Put the sign in front of Infinity */
847 p4[nb - 9] = (gfc_char4_t) fin;
853 /* We have room, so output 'Infinity' */
854 memcpy(p + nb - 8, "Infinity", 8);
856 /* For the case of width equals 8, there is not enough room
857 for the sign and 'Infinity' so we go with 'Inf' */
858 memcpy(p + nb - 3, "Inf", 3);
860 if (sign == S_PLUS || sign == S_MINUS)
862 if (nb < 9 && nb > 3)
863 p[nb - 4] = fin; /* Put the sign in front of Inf */
865 p[nb - 9] = fin; /* Put the sign in front of Infinity */
870 if (unlikely (is_char4_unit (dtp)))
872 gfc_char4_t *p4 = (gfc_char4_t *) p;
873 memcpy4 (p4 + nb - 3, "NaN", 3);
876 memcpy(p + nb - 3, "NaN", 3);
883 /* Returns the value of 10**d. */
885 #define CALCULATE_EXP(x) \
886 static GFC_REAL_ ## x \
887 calculate_exp_ ## x (int d)\
890 GFC_REAL_ ## x r = 1.0;\
891 for (i = 0; i< (d >= 0 ? d : -d); i++)\
893 r = (d >= 0) ? r : 1.0 / r;\
901 #ifdef HAVE_GFC_REAL_10
905 #ifdef HAVE_GFC_REAL_16
911 /* Define a macro to build code for write_float. */
913 /* Note: Before output_float is called, snprintf is used to print to buffer the
914 number in the format +D.DDDDe+ddd.
916 # The result will always contain a decimal point, even if no
919 - The converted value is to be left adjusted on the field boundary
921 + A sign (+ or -) always be placed before a number
923 * prec is used as the precision
925 e format: [-]d.ddde±dd where there is one digit before the
926 decimal-point character and the number of digits after it is
927 equal to the precision. The exponent always contains at least two
928 digits; if the value is zero, the exponent is 00. */
931 #define TOKENPASTE(x, y) TOKENPASTE2(x, y)
932 #define TOKENPASTE2(x, y) x ## y
934 #define DTOA(suff,prec,val) TOKENPASTE(DTOA2,suff)(prec,val)
936 #define DTOA2(prec,val) \
937 snprintf (buffer, size, "%+-#.*e", (prec), (val))
939 #define DTOA2L(prec,val) \
940 snprintf (buffer, size, "%+-#.*Le", (prec), (val))
943 #if defined(GFC_REAL_16_IS_FLOAT128)
944 #define DTOA2Q(prec,val) \
945 __qmath_(quadmath_snprintf) (buffer, size, "%+-#.*Qe", (prec), (val))
948 #define FDTOA(suff,prec,val) TOKENPASTE(FDTOA2,suff)(prec,val)
950 /* For F format, we print to the buffer with f format. */
951 #define FDTOA2(prec,val) \
952 snprintf (buffer, size, "%+-#.*f", (prec), (val))
954 #define FDTOA2L(prec,val) \
955 snprintf (buffer, size, "%+-#.*Lf", (prec), (val))
958 #if defined(GFC_REAL_16_IS_FLOAT128)
959 #define FDTOA2Q(prec,val) \
960 __qmath_(quadmath_snprintf) (buffer, size, "%+-#.*Qf", \
965 #if defined(GFC_REAL_16_IS_FLOAT128)
966 #define ISFINITE2Q(val) finiteq(val)
968 #define ISFINITE2(val) isfinite(val)
969 #define ISFINITE2L(val) isfinite(val)
971 #define ISFINITE(suff,val) TOKENPASTE(ISFINITE2,suff)(val)
974 #if defined(GFC_REAL_16_IS_FLOAT128)
975 #define SIGNBIT2Q(val) signbitq(val)
977 #define SIGNBIT2(val) signbit(val)
978 #define SIGNBIT2L(val) signbit(val)
980 #define SIGNBIT(suff,val) TOKENPASTE(SIGNBIT2,suff)(val)
983 #if defined(GFC_REAL_16_IS_FLOAT128)
984 #define ISNAN2Q(val) isnanq(val)
986 #define ISNAN2(val) isnan(val)
987 #define ISNAN2L(val) isnan(val)
989 #define ISNAN(suff,val) TOKENPASTE(ISNAN2,suff)(val)
993 /* Generate corresponding I/O format for FMT_G and output.
994 The rules to translate FMT_G to FMT_E or FMT_F from DEC fortran
995 LRM (table 11-2, Chapter 11, "I/O Formatting", P11-25) is:
997 Data Magnitude Equivalent Conversion
998 0< m < 0.1-0.5*10**(-d-1) Ew.d[Ee]
999 m = 0 F(w-n).(d-1), n' '
1000 0.1-0.5*10**(-d-1)<= m < 1-0.5*10**(-d) F(w-n).d, n' '
1001 1-0.5*10**(-d)<= m < 10-0.5*10**(-d+1) F(w-n).(d-1), n' '
1002 10-0.5*10**(-d+1)<= m < 100-0.5*10**(-d+2) F(w-n).(d-2), n' '
1003 ................ ..........
1004 10**(d-1)-0.5*10**(-1)<= m <10**d-0.5 F(w-n).0,n(' ')
1005 m >= 10**d-0.5 Ew.d[Ee]
1007 notes: for Gw.d , n' ' means 4 blanks
1008 for Gw.dEe, n' ' means e+2 blanks
1009 for rounding modes adjustment, r, See Fortran F2008 10.7.5.2.2
1010 the asm volatile is required for 32-bit x86 platforms. */
1012 #define OUTPUT_FLOAT_FMT_G(x,y) \
1014 output_float_FMT_G_ ## x (st_parameter_dt *dtp, const fnode *f, \
1015 GFC_REAL_ ## x m, char *buffer, size_t size, \
1016 int sign_bit, bool zero_flag, int comp_d) \
1018 int e = f->u.real.e;\
1019 int d = f->u.real.d;\
1020 int w = f->u.real.w;\
1022 GFC_REAL_ ## x exp_d, r = 0.5, r_sc;\
1023 int low, high, mid;\
1024 int ubound, lbound;\
1025 char *p, pad = ' ';\
1026 int save_scale_factor, nb = 0;\
1028 int nprinted, precision;\
1029 volatile GFC_REAL_ ## x temp;\
1031 save_scale_factor = dtp->u.p.scale_factor;\
1033 switch (dtp->u.p.current_unit->round_status)\
1036 r = sign_bit ? 1.0 : 0.0;\
1048 exp_d = calculate_exp_ ## x (d);\
1049 r_sc = (1 - r / exp_d);\
1051 if ((m > 0.0 && ((m < temp) || (r >= (exp_d - m))))\
1052 || ((m == 0.0) && !(compile_options.allow_std\
1053 & (GFC_STD_F2003 | GFC_STD_F2008)))\
1056 newf.format = FMT_E;\
1058 newf.u.real.d = d - comp_d;\
1061 precision = determine_precision (dtp, &newf, x);\
1062 nprinted = DTOA(y,precision,m); \
1072 while (low <= high)\
1074 mid = (low + high) / 2;\
1076 temp = (calculate_exp_ ## x (mid - 1) * r_sc);\
1081 if (ubound == lbound + 1)\
1088 if (ubound == lbound + 1)\
1102 nb = e <= 0 ? 4 : e + 2;\
1103 nb = nb >= w ? w - 1 : nb;\
1104 newf.format = FMT_F;\
1105 newf.u.real.w = w - nb;\
1106 newf.u.real.d = m == 0.0 ? d - 1 : -(mid - d - 1) ;\
1107 dtp->u.p.scale_factor = 0;\
1108 precision = determine_precision (dtp, &newf, x); \
1109 nprinted = FDTOA(y,precision,m); \
1112 result = output_float (dtp, &newf, buffer, size, nprinted, precision,\
1113 sign_bit, zero_flag);\
1114 dtp->u.p.scale_factor = save_scale_factor;\
1117 if (nb > 0 && !dtp->u.p.g0_no_blanks)\
1119 p = write_block (dtp, nb);\
1124 if (unlikely (is_char4_unit (dtp)))\
1126 gfc_char4_t *p4 = (gfc_char4_t *) p;\
1127 memset4 (p4, pad, nb);\
1130 memset (p, pad, nb);\
1134 OUTPUT_FLOAT_FMT_G(4,)
1136 OUTPUT_FLOAT_FMT_G(8,)
1138 #ifdef HAVE_GFC_REAL_10
1139 OUTPUT_FLOAT_FMT_G(10,L)
1142 #ifdef HAVE_GFC_REAL_16
1143 # ifdef GFC_REAL_16_IS_FLOAT128
1144 OUTPUT_FLOAT_FMT_G(16,Q)
1146 OUTPUT_FLOAT_FMT_G(16,L)
1150 #undef OUTPUT_FLOAT_FMT_G
1153 /* EN format is tricky since the number of significant digits depends
1154 on the magnitude. Solve it by first printing a temporary value and
1155 figure out the number of significant digits from the printed
1158 #define EN_PREC(x,y)\
1160 GFC_REAL_ ## x tmp; \
1161 tmp = * (GFC_REAL_ ## x *)source; \
1162 if (ISFINITE (y,tmp)) \
1163 nprinted = DTOA(y,0,tmp); \
1169 determine_en_precision (st_parameter_dt *dtp, const fnode *f,
1170 const char *source, int len)
1174 const size_t size = 10;
1186 #ifdef HAVE_GFC_REAL_10
1191 #ifdef HAVE_GFC_REAL_16
1193 # ifdef GFC_REAL_16_IS_FLOAT128
1201 internal_error (NULL, "bad real kind");
1207 int e = atoi (&buffer[5]);
1208 int nbefore; /* digits before decimal point - 1. */
1215 nbefore = 3 - nbefore;
1217 int prec = f->u.real.d + nbefore;
1218 if (dtp->u.p.current_unit->round_status != ROUND_UNSPECIFIED
1219 && dtp->u.p.current_unit->round_status != ROUND_PROCDEFINED)
1220 prec += 2 * len + 4;
1225 #define WRITE_FLOAT(x,y)\
1227 GFC_REAL_ ## x tmp;\
1228 tmp = * (GFC_REAL_ ## x *)source;\
1229 sign_bit = SIGNBIT (y,tmp);\
1230 if (!ISFINITE (y,tmp))\
1232 write_infnan (dtp, f, ISNAN (y,tmp), sign_bit);\
1235 tmp = sign_bit ? -tmp : tmp;\
1236 zero_flag = (tmp == 0.0);\
1237 if (f->format == FMT_G)\
1238 output_float_FMT_G_ ## x (dtp, f, tmp, buffer, size, sign_bit, \
1239 zero_flag, comp_d);\
1242 if (f->format == FMT_F)\
1243 nprinted = FDTOA(y,precision,tmp); \
1245 nprinted = DTOA(y,precision,tmp); \
1246 output_float (dtp, f, buffer, size, nprinted, precision,\
1247 sign_bit, zero_flag);\
1251 /* Output a real number according to its format. */
1254 write_float (st_parameter_dt *dtp, const fnode *f, const char *source, \
1255 int len, int comp_d)
1257 int sign_bit, nprinted;
1258 int precision; /* Precision for snprintf call. */
1261 if (f->format != FMT_EN)
1262 precision = determine_precision (dtp, f, len);
1264 precision = determine_en_precision (dtp, f, source, len);
1266 /* 4932 is the maximum exponent of long double and quad precision, 3
1267 extra characters for the sign, the decimal point, and the
1268 trailing null, and finally some extra digits depending on the
1269 requested precision. */
1270 const size_t size = 4932 + 3 + precision;
1283 #ifdef HAVE_GFC_REAL_10
1288 #ifdef HAVE_GFC_REAL_16
1290 # ifdef GFC_REAL_16_IS_FLOAT128
1298 internal_error (NULL, "bad real kind");