1 #include "flang/Decimal/decimal.h"
2 #include "llvm/Support/raw_ostream.h"
7 using namespace Fortran::decimal
;
17 llvm::raw_ostream
&failed(float x
) {
21 llvm::outs() << "FAIL: 0x";
22 return llvm::outs().write_hex(u
.u
);
25 void testDirect(float x
, const char *expect
, int expectExpo
, int flags
= 0) {
28 auto result
{ConvertFloatToDecimal(buffer
, sizeof buffer
,
29 static_cast<enum DecimalConversionFlags
>(flags
), 1024, RoundNearest
, x
)};
30 if (result
.str
== nullptr) {
31 failed(x
) << ' ' << flags
<< ": no result str\n";
32 } else if (std::strcmp(result
.str
, expect
) != 0 ||
33 result
.decimalExponent
!= expectExpo
) {
34 failed(x
) << ' ' << flags
<< ": expect '." << expect
<< 'e' << expectExpo
35 << "', got '." << result
.str
<< 'e' << result
.decimalExponent
40 void testReadback(float x
, int flags
) {
43 auto result
{ConvertFloatToDecimal(buffer
, sizeof buffer
,
44 static_cast<enum DecimalConversionFlags
>(flags
), 1024, RoundNearest
, x
)};
45 if (result
.str
== nullptr) {
46 failed(x
) << ' ' << flags
<< ": no result str\n";
49 char *q
{const_cast<char *>(result
.str
)};
50 int expo
{result
.decimalExponent
};
51 expo
-= result
.length
;
52 if (*q
== '-' || *q
== '+') {
55 if (q
>= buffer
&& q
< buffer
+ sizeof buffer
) {
56 std::snprintf(q
+ result
.length
,
57 buffer
+ sizeof buffer
- (q
+ result
.length
), "e%d", expo
);
60 auto rflags
{ConvertDecimalToFloat(&p
, &y
, RoundNearest
)};
63 if (y
== y
|| *p
!= '\0' || (rflags
& Invalid
)) {
65 (failed(x
) << " (NaN) " << flags
<< ": -> '" << result
.str
<< "' -> 0x")
67 << " '" << p
<< "' " << rflags
<< '\n';
69 } else if (x
!= y
|| *p
!= '\0' || (rflags
& Invalid
)) {
71 (failed(x
) << ' ' << flags
<< ": -> '" << result
.str
<< "' -> 0x")
73 << " '" << p
<< "' " << rflags
<< '\n';
80 testDirect(-1.0, "-1", 1);
81 testDirect(0.0, "0", 0);
82 testDirect(0.0, "+0", 0, AlwaysSign
);
83 testDirect(1.0, "1", 1);
84 testDirect(2.0, "2", 1);
85 testDirect(-1.0, "-1", 1);
86 testDirect(314159, "314159", 6);
87 testDirect(0.0625, "625", -1);
89 testDirect(u
.x
, "-0", 0);
91 testDirect(u
.x
, "Inf", 0);
92 testDirect(u
.x
, "+Inf", 0, AlwaysSign
);
94 testDirect(u
.x
, "-Inf", 0);
96 testDirect(u
.x
, "NaN", 0);
97 testDirect(u
.x
, "NaN", 0, AlwaysSign
);
100 "140129846432481707092372958328991613128026194187651577175706828388979108"
101 "268586060148663818836212158203125",
103 testDirect(u
.x
, "1", -44, Minimize
);
105 testDirect(u
.x
, "3289396118917826996438159226753253376", 39, 0);
106 testDirect(u
.x
, "32893961", 39, Minimize
);
107 for (u
.u
= 0; u
.u
< 16; ++u
.u
) {
108 testReadback(u
.x
, 0);
109 testReadback(-u
.x
, 0);
110 testReadback(u
.x
, Minimize
);
111 testReadback(-u
.x
, Minimize
);
113 for (u
.u
= 1; u
.u
< 0x7f800000; u
.u
*= 2) {
114 testReadback(u
.x
, 0);
115 testReadback(-u
.x
, 0);
116 testReadback(u
.x
, Minimize
);
117 testReadback(-u
.x
, Minimize
);
119 for (u
.u
= 0x7f7ffff0; u
.u
< 0x7f800010; ++u
.u
) {
120 testReadback(u
.x
, 0);
121 testReadback(-u
.x
, 0);
122 testReadback(u
.x
, Minimize
);
123 testReadback(-u
.x
, Minimize
);
125 for (u
.u
= 0; u
.u
< 0x7f800000; u
.u
+= 65536) {
126 testReadback(u
.x
, 0);
127 testReadback(-u
.x
, 0);
128 testReadback(u
.x
, Minimize
);
129 testReadback(-u
.x
, Minimize
);
131 for (u
.u
= 0; u
.u
< 0x7f800000; u
.u
+= 99999) {
132 testReadback(u
.x
, 0);
133 testReadback(-u
.x
, 0);
134 testReadback(u
.x
, Minimize
);
135 testReadback(-u
.x
, Minimize
);
137 for (u
.u
= 0; u
.u
< 0x7f800000; u
.u
+= 32767) {
138 testReadback(u
.x
, 0);
139 testReadback(-u
.x
, 0);
140 testReadback(u
.x
, Minimize
);
141 testReadback(-u
.x
, Minimize
);
143 llvm::outs() << tests
<< " tests run, " << fails
<< " tests failed\n";