Warning: This file is not a C or C++ file. It does not have highlighting.
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 "flang/Common/api-attrs.h" |
16 | #include <stddef.h> |
17 | |
18 | #ifdef __cplusplus |
19 | // Binary-to-decimal conversions (formatting) produce a sequence of decimal |
20 | // digit characters in a NUL-terminated user-supplied buffer that constitute |
21 | // a decimal fraction (or zero), accompanied by a decimal exponent that |
22 | // you'll get to adjust and format yourself. There can be a leading sign |
23 | // character. |
24 | // Negative zero is "-0". The result can also be "NaN", "Inf", "+Inf", |
25 | // or "-Inf". |
26 | // If the conversion can't fit in the user-supplied buffer, a null pointer |
27 | // is returned. |
28 | |
29 | #include "binary-floating-point.h" |
30 | namespace Fortran::decimal { |
31 | #endif /* C++ */ |
32 | |
33 | enum ConversionResultFlags { |
34 | Exact = 0, |
35 | Overflow = 1, |
36 | Inexact = 2, |
37 | Invalid = 4, |
38 | Underflow = 8, |
39 | }; |
40 | |
41 | struct ConversionToDecimalResult { |
42 | const char *str; /* may not be original buffer pointer; null if overflow */ |
43 | size_t length; /* does not include NUL terminator */ |
44 | int decimalExponent; /* assuming decimal point to the left of first digit */ |
45 | enum ConversionResultFlags flags; |
46 | }; |
47 | |
48 | /* The "minimize" flag causes the fewest number of output digits |
49 | * to be emitted such that reading them back into the same binary |
50 | * floating-point format with RoundNearest will return the same |
51 | * value. |
52 | */ |
53 | enum DecimalConversionFlags { |
54 | Minimize = 1, /* Minimize # of digits */ |
55 | AlwaysSign = 2, /* emit leading '+' if not negative */ |
56 | }; |
57 | |
58 | /* |
59 | * When allocating decimal conversion output buffers, use the maximum |
60 | * number of significant decimal digits in the representation of the |
61 | * least nonzero value, and add this extra space for a sign, a NUL, and |
62 | * some extra due to the library working internally in base 10**16 |
63 | * and computing its output size in multiples of 16. |
64 | */ |
65 | #define EXTRA_DECIMAL_CONVERSION_SPACE (1 + 1 + 2 * 16 - 1) |
66 | |
67 | #ifdef __cplusplus |
68 | template <int PREC> |
69 | RT_API_ATTRS ConversionToDecimalResult ConvertToDecimal(char *, size_t, |
70 | DecimalConversionFlags, int digits, enum FortranRounding rounding, |
71 | BinaryFloatingPointNumber<PREC> x); |
72 | |
73 | extern template RT_API_ATTRS ConversionToDecimalResult ConvertToDecimal<8>( |
74 | char *, size_t, enum DecimalConversionFlags, int, enum FortranRounding, |
75 | BinaryFloatingPointNumber<8>); |
76 | extern template RT_API_ATTRS ConversionToDecimalResult ConvertToDecimal<11>( |
77 | char *, size_t, enum DecimalConversionFlags, int, enum FortranRounding, |
78 | BinaryFloatingPointNumber<11>); |
79 | extern template RT_API_ATTRS ConversionToDecimalResult ConvertToDecimal<24>( |
80 | char *, size_t, enum DecimalConversionFlags, int, enum FortranRounding, |
81 | BinaryFloatingPointNumber<24>); |
82 | extern template RT_API_ATTRS ConversionToDecimalResult ConvertToDecimal<53>( |
83 | char *, size_t, enum DecimalConversionFlags, int, enum FortranRounding, |
84 | BinaryFloatingPointNumber<53>); |
85 | extern template RT_API_ATTRS ConversionToDecimalResult ConvertToDecimal<64>( |
86 | char *, size_t, enum DecimalConversionFlags, int, enum FortranRounding, |
87 | BinaryFloatingPointNumber<64>); |
88 | extern template RT_API_ATTRS ConversionToDecimalResult ConvertToDecimal<113>( |
89 | char *, size_t, enum DecimalConversionFlags, int, enum FortranRounding, |
90 | BinaryFloatingPointNumber<113>); |
91 | |
92 | template <int PREC> struct ConversionToBinaryResult { |
93 | BinaryFloatingPointNumber<PREC> binary; |
94 | enum ConversionResultFlags flags { Exact }; |
95 | }; |
96 | |
97 | template <int PREC> |
98 | RT_API_ATTRS ConversionToBinaryResult<PREC> ConvertToBinary(const char *&, |
99 | enum FortranRounding = RoundNearest, const char *end = nullptr); |
100 | |
101 | extern template RT_API_ATTRS ConversionToBinaryResult<8> ConvertToBinary<8>( |
102 | const char *&, enum FortranRounding, const char *end); |
103 | extern template RT_API_ATTRS ConversionToBinaryResult<11> ConvertToBinary<11>( |
104 | const char *&, enum FortranRounding, const char *end); |
105 | extern template RT_API_ATTRS ConversionToBinaryResult<24> ConvertToBinary<24>( |
106 | const char *&, enum FortranRounding, const char *end); |
107 | extern template RT_API_ATTRS ConversionToBinaryResult<53> ConvertToBinary<53>( |
108 | const char *&, enum FortranRounding, const char *end); |
109 | extern template RT_API_ATTRS ConversionToBinaryResult<64> ConvertToBinary<64>( |
110 | const char *&, enum FortranRounding, const char *end); |
111 | extern template RT_API_ATTRS ConversionToBinaryResult<113> ConvertToBinary<113>( |
112 | const char *&, enum FortranRounding, const char *end); |
113 | } // namespace Fortran::decimal |
114 | extern "C" { |
115 | #define NS(x) Fortran::decimal::x |
116 | #else /* C++ */ |
117 | #define NS(x) x |
118 | #endif /* C++ */ |
119 | |
120 | RT_API_ATTRS struct NS(ConversionToDecimalResult) |
121 | ConvertFloatToDecimal(char *, size_t, enum NS(DecimalConversionFlags), |
122 | int digits, enum NS(FortranRounding), float); |
123 | RT_API_ATTRS struct NS(ConversionToDecimalResult) |
124 | ConvertDoubleToDecimal(char *, size_t, enum NS(DecimalConversionFlags), |
125 | int digits, enum NS(FortranRounding), double); |
126 | RT_API_ATTRS struct NS(ConversionToDecimalResult) |
127 | ConvertLongDoubleToDecimal(char *, size_t, enum NS(DecimalConversionFlags), |
128 | int digits, enum NS(FortranRounding), long double); |
129 | |
130 | RT_API_ATTRS enum NS(ConversionResultFlags) |
131 | ConvertDecimalToFloat(const char **, float *, enum NS(FortranRounding)); |
132 | RT_API_ATTRS enum NS(ConversionResultFlags) |
133 | ConvertDecimalToDouble(const char **, double *, enum NS(FortranRounding)); |
134 | RT_API_ATTRS enum NS(ConversionResultFlags) ConvertDecimalToLongDouble( |
135 | const char **, long double *, enum NS(FortranRounding)); |
136 | #undef NS |
137 | #ifdef __cplusplus |
138 | } // extern "C" |
139 | #endif |
140 | #endif |
141 |
Warning: This file is not a C or C++ file. It does not have highlighting.