1 #include "flang/Decimal/decimal.h"
2 #include "llvm/Support/raw_ostream.h"
7 static constexpr int incr
{1}; // steps through all values
8 static constexpr bool doNegative
{true};
9 static constexpr bool doMinimize
{true};
11 using namespace Fortran::decimal
;
13 static std::uint64_t tests
{0};
14 static std::uint64_t fails
{0};
21 llvm::raw_ostream
&failed(float x
) {
25 llvm::outs() << "FAIL: 0x";
26 return llvm::outs().write_hex(u
.u
);
29 void testReadback(float x
, int flags
) {
33 if (!(tests
& 0x3fffff)) {
34 llvm::errs() << "\n0x";
35 llvm::errs().write_hex(u
.u
) << ' ';
36 } else if (!(tests
& 0xffff)) {
40 auto result
{ConvertFloatToDecimal(buffer
, sizeof buffer
,
41 static_cast<enum DecimalConversionFlags
>(flags
), 1024, RoundNearest
, x
)};
42 if (result
.str
== nullptr) {
43 failed(x
) << ' ' << flags
<< ": no result str\n";
46 char *q
{const_cast<char *>(result
.str
)};
47 if ((*q
>= '0' && *q
<= '9') ||
48 ((*q
== '-' || *q
== '+') && q
[1] >= '0' && q
[1] <= '9')) {
49 int expo
{result
.decimalExponent
};
50 expo
-= result
.length
;
51 if (*q
== '-' || *q
== '+') {
54 std::snprintf(q
+ result
.length
,
55 buffer
+ sizeof buffer
- (q
+ result
.length
), "e%d", expo
);
58 auto rflags
{ConvertDecimalToFloat(&p
, &y
, RoundNearest
)};
60 if (y
== y
|| *p
!= '\0' || (rflags
& Invalid
)) {
62 failed(x
) << " (NaN) " << flags
<< ": -> '" << result
.str
<< "' -> 0x";
63 failed(x
).write_hex(u
.u
) << " '" << p
<< "' " << rflags
<< '\n';
65 } else if (x
!= y
|| *p
!= '\0' || (rflags
& Invalid
)) {
67 failed(x
) << ' ' << flags
<< ": -> '" << result
.str
<< "' -> 0x";
68 failed(x
).write_hex(u
.u
) << " '" << p
<< "' " << rflags
<< '\n';
75 for (u
.u
= 0; u
.u
< 0x7f800010; u
.u
+= incr
) {
77 if constexpr (doNegative
) {
78 testReadback(-u
.x
, 0);
80 if constexpr (doMinimize
) {
81 testReadback(u
.x
, Minimize
);
82 if constexpr (doNegative
) {
83 testReadback(-u
.x
, Minimize
);
87 llvm::outs() << '\n' << tests
<< " tests run, " << fails
<< " tests failed\n";