1 /* Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
2 Free Software Foundation, Inc.
3 Contributed by Andy Vaught
4 Write float code factoring to this file by Jerry DeLisle
5 F2003 I/O support contributed by Jerry DeLisle
7 This file is part of the GNU Fortran runtime library (libgfortran).
9 Libgfortran is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 Libgfortran is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 Under Section 7 of GPL version 3, you are granted additional
20 permissions described in the GCC Runtime Library Exception, version
21 3.1, as published by the Free Software Foundation.
23 You should have received a copy of the GNU General Public License and
24 a copy of the GCC Runtime Library Exception along with this program;
25 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
26 <http://www.gnu.org/licenses/>. */
31 { S_NONE, S_MINUS, S_PLUS }
34 /* Given a flag that indicates if a value is negative or not, return a
35 sign_t that gives the sign that we need to produce. */
38 calculate_sign (st_parameter_dt *dtp, int negative_flag)
45 switch (dtp->u.p.sign_status)
47 case SIGN_SP: /* Show sign. */
50 case SIGN_SS: /* Suppress sign. */
53 case SIGN_S: /* Processor defined. */
54 case SIGN_UNSPECIFIED:
55 s = options.optional_plus ? S_PLUS : S_NONE;
63 /* Determine the precision except for EN format. For G format,
64 determines an upper bound to be used for sizing the buffer. */
67 determine_precision (st_parameter_dt * dtp, const fnode * f, int len)
69 int precision = f->u.real.d;
75 precision += dtp->u.p.scale_factor;
78 /* Scale factor has no effect on output. */
82 /* See F2008 10.7.2.3.3.6 */
83 if (dtp->u.p.scale_factor <= 0)
84 precision += dtp->u.p.scale_factor - 1;
90 /* If the scale factor has a large negative value, we must do our
91 own rounding? Use ROUND='NEAREST', which should be what snprintf
94 (dtp->u.p.current_unit->round_status == ROUND_UNSPECIFIED
95 || dtp->u.p.current_unit->round_status == ROUND_PROCDEFINED))
96 dtp->u.p.current_unit->round_status = ROUND_NEAREST;
98 /* Add extra guard digits up to at least full precision when we do
100 if (dtp->u.p.current_unit->round_status != ROUND_UNSPECIFIED
101 && dtp->u.p.current_unit->round_status != ROUND_PROCDEFINED)
103 precision += 2 * len + 4;
112 /* Output a real number according to its format which is FMT_G free. */
115 output_float (st_parameter_dt *dtp, const fnode *f, char *buffer, size_t size,
116 int nprinted, int precision, int sign_bit, bool zero_flag)
123 /* Number of digits before the decimal point. */
125 /* Number of zeros after the decimal point. */
127 /* Number of digits after the decimal point. */
129 /* Number of zeros after the decimal point, whatever the precision. */
133 int ndigits, edigits;
139 p = dtp->u.p.scale_factor;
144 /* We should always know the field width and precision. */
146 internal_error (&dtp->common, "Unspecified precision");
148 sign = calculate_sign (dtp, sign_bit);
150 /* Calculate total number of digits. */
152 ndigits = nprinted - 2;
154 ndigits = precision + 1;
156 /* Read the exponent back in. */
158 e = atoi (&buffer[ndigits + 3]) + 1;
162 /* Make sure zero comes out as 0.0e0. */
166 /* Normalize the fractional component. */
169 buffer[2] = buffer[1];
175 /* Figure out where to place the decimal point. */
179 nbefore = ndigits - precision;
180 /* Make sure the decimal point is a '.'; depending on the
181 locale, this might not be the case otherwise. */
182 digits[nbefore] = '.';
188 memmove (digits + nbefore, digits + nbefore + 1, p);
189 digits[nbefore + p] = '.';
195 nzero = nzero_real = 0;
199 if (nbefore + p >= 0)
202 memmove (digits + nbefore + p + 1, digits + nbefore + p, -p);
204 digits[nbefore] = '.';
209 nzero = -(nbefore + p);
210 memmove (digits + 1, digits, nbefore);
212 nafter = d + nbefore;
222 nzero = nzero_real = 0;
226 while (digits[0] == '0' && nbefore > 0)
234 /* If we need to do rounding ourselves, get rid of the dot by
235 moving the fractional part. */
236 if (dtp->u.p.current_unit->round_status != ROUND_UNSPECIFIED
237 && dtp->u.p.current_unit->round_status != ROUND_PROCDEFINED)
238 memmove (digits + nbefore, digits + nbefore + 1, ndigits - nbefore);
243 i = dtp->u.p.scale_factor;
244 if (d <= 0 && p == 0)
246 generate_error (&dtp->common, LIBERROR_FORMAT, "Precision not "
247 "greater than zero in format specifier 'E' or 'D'");
250 if (p <= -d || p >= d + 2)
252 generate_error (&dtp->common, LIBERROR_FORMAT, "Scale factor "
253 "out of range in format specifier 'E' or 'D'");
269 nafter = (d - p) + 1;
285 /* The exponent must be a multiple of three, with 1-3 digits before
286 the decimal point. */
295 nbefore = 3 - nbefore;
314 /* Should never happen. */
315 internal_error (&dtp->common, "Unexpected format token");
321 /* Round the value. The value being rounded is an unsigned magnitude. */
322 switch (dtp->u.p.current_unit->round_status)
324 /* For processor defined and unspecified rounding we use
325 snprintf to print the exact number of digits needed, and thus
326 let snprintf handle the rounding. On system claiming support
327 for IEEE 754, this ought to be round to nearest, ties to
328 even, corresponding to the Fortran ROUND='NEAREST'. */
329 case ROUND_PROCDEFINED:
330 case ROUND_UNSPECIFIED:
331 case ROUND_ZERO: /* Do nothing and truncation occurs. */
342 /* Round compatible unless there is a tie. A tie is a 5 with
343 all trailing zero's. */
344 i = nafter + nbefore;
345 if (digits[i] == '5')
347 for(i++ ; i < ndigits; i++)
349 if (digits[i] != '0')
352 /* It is a tie so round to even. */
353 switch (digits[nafter + nbefore - 1])
360 /* If odd, round away from zero to even. */
363 /* If even, skip rounding, truncate to even. */
368 /* The ROUND_COMPATIBLE is rounding away from zero when there is a tie. */
369 case ROUND_COMPATIBLE:
377 if (w > 0 && d == 0 && p == 0)
379 /* Scan for trailing zeros to see if we really need to round it. */
380 for(i = nbefore + nafter; i < ndigits; i++)
382 if (digits[i] != '0')
389 if (nbefore + nafter == 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 /* Generate corresponding I/O format for FMT_G and output.
966 The rules to translate FMT_G to FMT_E or FMT_F from DEC fortran
967 LRM (table 11-2, Chapter 11, "I/O Formatting", P11-25) is:
969 Data Magnitude Equivalent Conversion
970 0< m < 0.1-0.5*10**(-d-1) Ew.d[Ee]
971 m = 0 F(w-n).(d-1), n' '
972 0.1-0.5*10**(-d-1)<= m < 1-0.5*10**(-d) F(w-n).d, n' '
973 1-0.5*10**(-d)<= m < 10-0.5*10**(-d+1) F(w-n).(d-1), n' '
974 10-0.5*10**(-d+1)<= m < 100-0.5*10**(-d+2) F(w-n).(d-2), n' '
975 ................ ..........
976 10**(d-1)-0.5*10**(-1)<= m <10**d-0.5 F(w-n).0,n(' ')
977 m >= 10**d-0.5 Ew.d[Ee]
979 notes: for Gw.d , n' ' means 4 blanks
980 for Gw.dEe, n' ' means e+2 blanks
981 for rounding modes adjustment, r, See Fortran F2008 10.7.5.2.2
982 the asm volatile is required for 32-bit x86 platforms. */
984 #define OUTPUT_FLOAT_FMT_G(x,y) \
986 output_float_FMT_G_ ## x (st_parameter_dt *dtp, const fnode *f, \
987 GFC_REAL_ ## x m, char *buffer, size_t size, \
988 int sign_bit, bool zero_flag, int comp_d) \
990 int e = f->u.real.e;\
991 int d = f->u.real.d;\
992 int w = f->u.real.w;\
994 GFC_REAL_ ## x rexp_d, r = 0.5;\
998 int save_scale_factor, nb = 0;\
1000 int nprinted, precision;\
1002 save_scale_factor = dtp->u.p.scale_factor;\
1004 switch (dtp->u.p.current_unit->round_status)\
1007 r = sign_bit ? 1.0 : 0.0;\
1019 rexp_d = calculate_exp_ ## x (-d);\
1020 if ((m > 0.0 && ((m < 0.1 - 0.1 * r * rexp_d) || (rexp_d * (m + r) >= 1.0)))\
1021 || ((m == 0.0) && !(compile_options.allow_std\
1022 & (GFC_STD_F2003 | GFC_STD_F2008))))\
1024 newf.format = FMT_E;\
1026 newf.u.real.d = d - comp_d;\
1029 precision = determine_precision (dtp, &newf, x);\
1030 nprinted = DTOA(y,precision,m); \
1040 while (low <= high)\
1042 volatile GFC_REAL_ ## x temp;\
1043 mid = (low + high) / 2;\
1045 temp = (calculate_exp_ ## x (mid - 1) * (1 - r * rexp_d));\
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);\
1091 if (result == FAILURE)\
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
1127 #define EN_PREC(x,y)\
1129 GFC_REAL_ ## x tmp; \
1130 tmp = * (GFC_REAL_ ## x *)source; \
1131 if (isfinite (tmp)) \
1132 nprinted = DTOA(y,0,tmp); \
1138 determine_en_precision (st_parameter_dt *dtp, const fnode *f,
1139 const char *source, int len)
1143 const size_t size = 10;
1155 #ifdef HAVE_GFC_REAL_10
1160 #ifdef HAVE_GFC_REAL_16
1162 # ifdef GFC_REAL_16_IS_FLOAT128
1170 internal_error (NULL, "bad real kind");
1176 int e = atoi (&buffer[5]);
1177 int nbefore; /* digits before decimal point - 1. */
1184 nbefore = 3 - nbefore;
1186 int prec = f->u.real.d + nbefore;
1187 if (dtp->u.p.current_unit->round_status != ROUND_UNSPECIFIED
1188 && dtp->u.p.current_unit->round_status != ROUND_PROCDEFINED)
1189 prec += 2 * len + 4;
1194 #define WRITE_FLOAT(x,y)\
1196 GFC_REAL_ ## x tmp;\
1197 tmp = * (GFC_REAL_ ## x *)source;\
1198 sign_bit = signbit (tmp);\
1199 if (!isfinite (tmp))\
1201 write_infnan (dtp, f, isnan (tmp), sign_bit);\
1204 tmp = sign_bit ? -tmp : tmp;\
1205 zero_flag = (tmp == 0.0);\
1206 if (f->format == FMT_G)\
1207 output_float_FMT_G_ ## x (dtp, f, tmp, buffer, size, sign_bit, \
1208 zero_flag, comp_d);\
1211 if (f->format == FMT_F)\
1212 nprinted = FDTOA(y,precision,tmp); \
1214 nprinted = DTOA(y,precision,tmp); \
1215 output_float (dtp, f, buffer, size, nprinted, precision,\
1216 sign_bit, zero_flag);\
1220 /* Output a real number according to its format. */
1223 write_float (st_parameter_dt *dtp, const fnode *f, const char *source, \
1224 int len, int comp_d)
1226 int sign_bit, nprinted;
1227 int precision; /* Precision for snprintf call. */
1230 if (f->format != FMT_EN)
1231 precision = determine_precision (dtp, f, len);
1233 precision = determine_en_precision (dtp, f, source, len);
1235 /* 4932 is the maximum exponent of long double and quad precision, 3
1236 extra characters for the sign, the decimal point, and the
1237 trailing null, and finally some extra digits depending on the
1238 requested precision. */
1239 const size_t size = 4932 + 3 + precision;
1252 #ifdef HAVE_GFC_REAL_10
1257 #ifdef HAVE_GFC_REAL_16
1259 # ifdef GFC_REAL_16_IS_FLOAT128
1267 internal_error (NULL, "bad real kind");