FLANG

decimal.h
1 /*===-- include/flang/Decimal/decimal.h ---------------------------*- C++ -*-===
2 *
3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 * See https://llvm.org/LICENSE.txt for license information.
5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 *
7 * ===-----------------------------------------------------------------------===
8 */
9
10 /* C and C++ API for binary-to/from-decimal conversion package. */
11
12 #ifndef FORTRAN_DECIMAL_DECIMAL_H_
13 #define FORTRAN_DECIMAL_DECIMAL_H_
14
15 #include <stddef.h>
16
17 #ifdef __cplusplus
18 // Binary-to-decimal conversions (formatting) produce a sequence of decimal
19 // digit characters in a NUL-terminated user-supplied buffer that constitute
20 // a decimal fraction (or zero), accompanied by a decimal exponent that
21 // you'll get to adjust and format yourself. There can be a leading sign
22 // character.
23 // Negative zero is "-0". The result can also be "NaN", "Inf", "+Inf",
24 // or "-Inf".
25 // If the conversion can't fit in the user-supplied buffer, a null pointer
26 // is returned.
27
28 #include "binary-floating-point.h"
29 namespace Fortran::decimal {
30 #endif /* C++ */
31
32 enum ConversionResultFlags {
33 Exact = 0,
34 Overflow = 1,
35 Inexact = 2,
36 Invalid = 4,
37 };
38
39 struct ConversionToDecimalResult {
40 const char *str; /* may not be original buffer pointer; null if overflow */
41 size_t length; /* does not include NUL terminator */
42 int decimalExponent; /* assuming decimal point to the left of first digit */
43 enum ConversionResultFlags flags;
44 };
45
46 enum FortranRounding {
47 RoundNearest, /* RN */
48 RoundUp, /* RU */
49 RoundDown, /* RD */
50 RoundToZero, /* RZ - no rounding */
51 RoundCompatible, /* RC: like RN, but ties go away from 0 */
52 RoundDefault, /* RP: maps to one of the above */
53 };
54
55 /* The "minimize" flag causes the fewest number of output digits
56 * to be emitted such that reading them back into the same binary
57 * floating-point format with RoundNearest will return the same
58 * value.
59 */
60 enum DecimalConversionFlags {
61 Minimize = 1, /* Minimize # of digits */
62 AlwaysSign = 2, /* emit leading '+' if not negative */
63 };
64
65 /*
66 * When allocating decimal conversion output buffers, use the maximum
67 * number of significant decimal digits in the representation of the
68 * least nonzero value, and add this extra space for a sign, a NUL, and
69 * some extra due to the library working internally in base 10**16
70 * and computing its output size in multiples of 16.
71 */
72 #define EXTRA_DECIMAL_CONVERSION_SPACE (1 + 1 + 2 * 16 - 1)
73
74 #ifdef __cplusplus
75 template <int PREC>
76 ConversionToDecimalResult ConvertToDecimal(char *, size_t,
77 DecimalConversionFlags, int digits, enum FortranRounding rounding,
78 BinaryFloatingPointNumber<PREC> x);
79
80 extern template ConversionToDecimalResult ConvertToDecimal<8>(char *, size_t,
81 enum DecimalConversionFlags, int, enum FortranRounding,
82 BinaryFloatingPointNumber<8>);
83 extern template ConversionToDecimalResult ConvertToDecimal<11>(char *, size_t,
84 enum DecimalConversionFlags, int, enum FortranRounding,
85 BinaryFloatingPointNumber<11>);
86 extern template ConversionToDecimalResult ConvertToDecimal<24>(char *, size_t,
87 enum DecimalConversionFlags, int, enum FortranRounding,
88 BinaryFloatingPointNumber<24>);
89 extern template ConversionToDecimalResult ConvertToDecimal<53>(char *, size_t,
90 enum DecimalConversionFlags, int, enum FortranRounding,
91 BinaryFloatingPointNumber<53>);
92 extern template ConversionToDecimalResult ConvertToDecimal<64>(char *, size_t,
93 enum DecimalConversionFlags, int, enum FortranRounding,
94 BinaryFloatingPointNumber<64>);
95 extern template ConversionToDecimalResult ConvertToDecimal<113>(char *, size_t,
96 enum DecimalConversionFlags, int, enum FortranRounding,
97 BinaryFloatingPointNumber<113>);
98
99 template <int PREC> struct ConversionToBinaryResult {
100 BinaryFloatingPointNumber<PREC> binary;
101 enum ConversionResultFlags flags { Exact };
102 };
103
104 template <int PREC>
105 ConversionToBinaryResult<PREC> ConvertToBinary(
106 const char *&, enum FortranRounding = RoundNearest);
107
108 extern template ConversionToBinaryResult<8> ConvertToBinary<8>(
109 const char *&, enum FortranRounding = RoundNearest);
110 extern template ConversionToBinaryResult<11> ConvertToBinary<11>(
111 const char *&, enum FortranRounding = RoundNearest);
112 extern template ConversionToBinaryResult<24> ConvertToBinary<24>(
113 const char *&, enum FortranRounding = RoundNearest);
114 extern template ConversionToBinaryResult<53> ConvertToBinary<53>(
115 const char *&, enum FortranRounding = RoundNearest);
116 extern template ConversionToBinaryResult<64> ConvertToBinary<64>(
117 const char *&, enum FortranRounding = RoundNearest);
118 extern template ConversionToBinaryResult<113> ConvertToBinary<113>(
119 const char *&, enum FortranRounding = RoundNearest);
120 } // namespace Fortran::decimal
121 extern "C" {
122 #define NS(x) Fortran::decimal::x
123 #else /* C++ */
124 #define NS(x) x
125 #endif /* C++ */
126
127 struct NS(ConversionToDecimalResult)
128 ConvertFloatToDecimal(char *, size_t, enum NS(DecimalConversionFlags),
129 int digits, enum NS(FortranRounding), float);
130 struct NS(ConversionToDecimalResult)
131 ConvertDoubleToDecimal(char *, size_t, enum NS(DecimalConversionFlags),
132 int digits, enum NS(FortranRounding), double);
133 #if __x86_64__ && !defined(_MSC_VER)
134 struct NS(ConversionToDecimalResult)
135 ConvertLongDoubleToDecimal(char *, size_t, enum NS(DecimalConversionFlags),
136 int digits, enum NS(FortranRounding), long double);
137 #endif
138
139 enum NS(ConversionResultFlags)
140 ConvertDecimalToFloat(const char **, float *, enum NS(FortranRounding));
141 enum NS(ConversionResultFlags)
142 ConvertDecimalToDouble(const char **, double *, enum NS(FortranRounding));
143 #if __x86_64__ && !defined(_MSC_VER)
144 enum NS(ConversionResultFlags) ConvertDecimalToLongDouble(
145 const char **, long double *, enum NS(FortranRounding));
146 #endif
147 #undef NS
148 #ifdef __cplusplus
149 } // extern "C"
150 #endif
151 #endif
ConversionToDecimalResult
Definition: decimal.h:39