1 #include "flang/Decimal/decimal.h" 2 #include <cinttypes> 3 #include <cstdio> 4 #include <cstring> 5 #include <iostream> 6 7 static constexpr int incr{1}; // steps through all values 8 static constexpr bool doNegative{true}; 9 static constexpr bool doMinimize{true}; 10 11 using namespace Fortran::decimal; 12 13 static std::uint64_t tests{0}; 14 static std::uint64_t fails{0}; 15 16 union u { 17 float x; 18 std::uint32_t u; 19 }; 20 21 std::ostream &failed(float x) { 22 ++fails; 23 union u u; 24 u.x = x; 25 return std::cout << "FAIL: 0x" << std::hex << u.u << std::dec; 26 } 27 28 void testReadback(float x, int flags) { 29 char buffer[1024]; 30 union u u; 31 u.x = x; 32 if (!(tests & 0x3fffff)) { 33 std::cerr << "\n0x" << std::hex << u.u << std::dec << ' '; 34 } else if (!(tests & 0xffff)) { 35 std::cerr << '.'; 36 } 37 ++tests; 38 auto result{ConvertFloatToDecimal(buffer, sizeof buffer, 39 static_cast<enum DecimalConversionFlags>(flags), 1024, RoundNearest, x)}; 40 if (result.str == nullptr) { 41 failed(x) << ' ' << flags << ": no result str\n"; 42 } else { 43 float y{0}; 44 char *q{const_cast<char *>(result.str)}; 45 if ((*q >= '0' && *q <= '9') || 46 ((*q == '-' || *q == '+') && q[1] >= '0' && q[1] <= '9')) { 47 int expo{result.decimalExponent}; 48 expo -= result.length; 49 if (*q == '-' || *q == '+') { 50 ++expo; 51 } 52 std::sprintf(q + result.length, "e%d", expo); 53 } 54 const char *p{q}; 55 auto rflags{ConvertDecimalToFloat(&p, &y, RoundNearest)}; 56 if (!(x == x)) { 57 if (y == y || *p != '\0' || (rflags & Invalid)) { 58 u.x = y; 59 failed(x) << " (NaN) " << flags << ": -> '" << result.str << "' -> 0x" 60 << std::hex << u.u << std::dec << " '" << p << "' " << rflags 61 << '\n'; 62 } 63 } else if (x != y || *p != '\0' || (rflags & Invalid)) { 64 u.x = y; 65 failed(x) << ' ' << flags << ": -> '" << result.str << "' -> 0x" 66 << std::hex << u.u << std::dec << " '" << p << "' " << rflags 67 << '\n'; 68 } 69 } 70 } 71 72 int main() { 73 union u u; 74 for (u.u = 0; u.u < 0x7f800010; u.u += incr) { 75 testReadback(u.x, 0); 76 if constexpr (doNegative) { 77 testReadback(-u.x, 0); 78 } 79 if constexpr (doMinimize) { 80 testReadback(u.x, Minimize); 81 if constexpr (doNegative) { 82 testReadback(-u.x, Minimize); 83 } 84 } 85 } 86 std::cout << '\n' << tests << " tests run, " << fails << " tests failed\n"; 87 return fails > 0; 88 } 89