brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · dafb075 Raw
146 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 7using namespace Fortran::decimal;8 9static int tests{0};10static int fails{0};11 12union u {13  float x;14  std::uint32_t u;15};16 17llvm::raw_ostream &failed(float x) {18  ++fails;19  union u u;20  u.x = x;21  llvm::outs() << "FAIL: 0x";22  return llvm::outs().write_hex(u.u);23}24 25void testDirect(float x, const char *expect, int expectExpo, int flags = 0) {26  char buffer[1024];27  ++tests;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' << expectExpo35              << "', got '." << result.str << 'e' << result.decimalExponent36              << "'\n";37  }38}39 40void testReadback(float x, int flags) {41  char buffer[1024];42  ++tests;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";47  } else {48    float y{0};49    char *q{const_cast<char *>(result.str)};50    int expo{result.decimalExponent};51    expo -= result.length;52    if (*q == '-' || *q == '+') {53      ++expo;54    }55    if (q >= buffer && q < buffer + sizeof buffer) {56      std::snprintf(q + result.length,57          buffer + sizeof buffer - (q + result.length), "e%d", expo);58    }59    const char *p{q};60    auto rflags{ConvertDecimalToFloat(&p, &y, RoundNearest)};61    union u u;62    if (!(x == x)) {63      if (y == y || *p != '\0' || (rflags & Invalid)) {64        u.x = y;65        (failed(x) << " (NaN) " << flags << ": -> '" << result.str << "' -> 0x")66                .write_hex(u.u)67            << " '" << p << "' " << rflags << '\n';68      }69    } else if (x != y || *p != '\0' || (rflags & Invalid)) {70      u.x = x;71      (failed(x) << ' ' << flags << ": -> '" << result.str << "' -> 0x")72              .write_hex(u.u)73          << " '" << p << "' " << rflags << '\n';74    }75  }76}77 78int main() {79  union u u;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);88  u.u = 0x80000000;89  testDirect(u.x, "-0", 0);90  u.u = 0x7f800000;91  testDirect(u.x, "Inf", 0);92  testDirect(u.x, "+Inf", 0, AlwaysSign);93  u.u = 0xff800000;94  testDirect(u.x, "-Inf", 0);95  u.u = 0xffffffff;96  testDirect(u.x, "NaN", 0);97  testDirect(u.x, "NaN", 0, AlwaysSign);98  u.u = 1;99  testDirect(u.x,100      "140129846432481707092372958328991613128026194187651577175706828388979108"101      "268586060148663818836212158203125",102      -44, 0);103  testDirect(u.x, "1", -44, Minimize);104  u.u = 0x7f777777;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);112  }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);118  }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);124  }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);130  }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);136  }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);142  }143  llvm::outs() << tests << " tests run, " << fails << " tests failed\n";144  return fails > 0;145}146