brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.4 KiB · 46951f3 Raw
90 lines · cpp
1#include "flang/Decimal/decimal.h"2#include "llvm/Support/raw_ostream.h"3#include <cinttypes>4#include <cstdio>5#include <cstring>6 7static constexpr int incr{1}; // steps through all values8static constexpr bool doNegative{true};9static constexpr bool doMinimize{true};10 11using namespace Fortran::decimal;12 13static std::uint64_t tests{0};14static std::uint64_t fails{0};15 16union u {17  float x;18  std::uint32_t u;19};20 21llvm::raw_ostream &failed(float x) {22  ++fails;23  union u u;24  u.x = x;25  llvm::outs() << "FAIL: 0x";26  return llvm::outs().write_hex(u.u);27}28 29void testReadback(float x, int flags) {30  char buffer[1024];31  union u u;32  u.x = x;33  if (!(tests & 0x3fffff)) {34    llvm::errs() << "\n0x";35    llvm::errs().write_hex(u.u) << ' ';36  } else if (!(tests & 0xffff)) {37    llvm::errs() << '.';38  }39  ++tests;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";44  } else {45    float y{0};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 == '+') {52        ++expo;53      }54      std::snprintf(q + result.length,55          buffer + sizeof buffer - (q + result.length), "e%d", expo);56    }57    const char *p{q};58    auto rflags{ConvertDecimalToFloat(&p, &y, RoundNearest)};59    if (!(x == x)) {60      if (y == y || *p != '\0' || (rflags & Invalid)) {61        u.x = y;62        failed(x) << " (NaN) " << flags << ": -> '" << result.str << "' -> 0x";63        failed(x).write_hex(u.u) << " '" << p << "' " << rflags << '\n';64      }65    } else if (x != y || *p != '\0' || (rflags & Invalid)) {66      u.x = y;67      failed(x) << ' ' << flags << ": -> '" << result.str << "' -> 0x";68      failed(x).write_hex(u.u) << " '" << p << "' " << rflags << '\n';69    }70  }71}72 73int main() {74  union u u;75  for (u.u = 0; u.u < 0x7f800010; u.u += incr) {76    testReadback(u.x, 0);77    if constexpr (doNegative) {78      testReadback(-u.x, 0);79    }80    if constexpr (doMinimize) {81      testReadback(u.x, Minimize);82      if constexpr (doNegative) {83        testReadback(-u.x, Minimize);84      }85    }86  }87  llvm::outs() << '\n' << tests << " tests run, " << fails << " tests failed\n";88  return fails > 0;89}90