[libc-commits] [libc] [libc][test] make `str_to_float_comparison_test` independent of C++ headers. (PR #133978)

Mikhail R. Gadelha via libc-commits libc-commits at lists.llvm.org
Sat Apr 5 09:27:46 PDT 2025


================
@@ -54,80 +56,112 @@ static inline uint64_t fastHexToU64(const char *inStr) {
   return result;
 }
 
-int checkFile(char *inputFileName, int *totalFails, int *totalBitDiffs,
-              int *detailedBitDiffs, int *total) {
-  int32_t curFails = 0;    // Only counts actual failures, not bitdiffs.
-  int32_t curBitDiffs = 0; // A bitdiff is when the expected result and actual
-                           // result are off by +/- 1 bit.
-  std::string line;
-  std::string num;
+static void parseLine(char *line, int *total, int *detailedBitDiffs,
+                      int32_t &curFails, int32_t &curBitDiffs) {
 
-  std::ifstream fileStream(inputFileName, std::ifstream::in);
-
-  if (!fileStream.is_open()) {
-    std::cout << "file '" << inputFileName << "' failed to open. Exiting.\n";
-    return 1;
+  if (line[0] == '#') {
+    return;
   }
-  while (getline(fileStream, line)) {
-    if (line[0] == '#') {
-      continue;
-    }
-    *total = *total + 1;
-    uint32_t expectedFloatRaw;
-    uint64_t expectedDoubleRaw;
+  *total = *total + 1;
+  uint32_t expectedFloatRaw;
+  uint64_t expectedDoubleRaw;
 
-    expectedFloatRaw = fastHexToU32(line.c_str() + 5);
-    expectedDoubleRaw = fastHexToU64(line.c_str() + 14);
-    num = line.substr(31);
+  expectedFloatRaw = fastHexToU32(line + 5);
+  expectedDoubleRaw = fastHexToU64(line + 14);
 
-    float floatResult = strtof(num.c_str(), nullptr);
+  char *num = line + 31;
 
-    double doubleResult = strtod(num.c_str(), nullptr);
+  float floatResult = LIBC_NAMESPACE::strtof(num, nullptr);
 
-    uint32_t floatRaw = *(uint32_t *)(&floatResult);
+  double doubleResult = LIBC_NAMESPACE::strtod(num, nullptr);
 
-    uint64_t doubleRaw = *(uint64_t *)(&doubleResult);
+  uint32_t floatRaw = LIBC_NAMESPACE::cpp::bit_cast<uint32_t>(floatResult);
 
-    if (!(expectedFloatRaw == floatRaw)) {
-      if (expectedFloatRaw == floatRaw + 1 ||
-          expectedFloatRaw == floatRaw - 1) {
-        curBitDiffs++;
-        if (expectedFloatRaw == floatRaw + 1) {
-          detailedBitDiffs[0] = detailedBitDiffs[0] + 1; // float low
-        } else {
-          detailedBitDiffs[1] = detailedBitDiffs[1] + 1; // float high
-        }
+  uint64_t doubleRaw = LIBC_NAMESPACE::cpp::bit_cast<uint64_t>(doubleResult);
+
+  if (!(expectedFloatRaw == floatRaw)) {
+    if (expectedFloatRaw == floatRaw + 1 || expectedFloatRaw == floatRaw - 1) {
+      curBitDiffs++;
+      if (expectedFloatRaw == floatRaw + 1) {
+        detailedBitDiffs[0] = detailedBitDiffs[0] + 1; // float low
       } else {
-        curFails++;
-      }
-      if (curFails + curBitDiffs < 10) {
-        std::cout << "Float fail for '" << num << "'. Expected " << std::hex
-                  << expectedFloatRaw << " but got " << floatRaw << "\n"
-                  << std::dec;
+        detailedBitDiffs[1] = detailedBitDiffs[1] + 1; // float high
       }
+    } else {
+      curFails++;
+    }
+    if (curFails + curBitDiffs < 10) {
+      LIBC_NAMESPACE::printf("Float fail for '%s'. Expected %x but got %x\n",
+                             num, expectedFloatRaw, floatRaw);
     }
+  }
 
-    if (!(expectedDoubleRaw == doubleRaw)) {
-      if (expectedDoubleRaw == doubleRaw + 1 ||
-          expectedDoubleRaw == doubleRaw - 1) {
-        curBitDiffs++;
-        if (expectedDoubleRaw == doubleRaw + 1) {
-          detailedBitDiffs[2] = detailedBitDiffs[2] + 1; // double low
-        } else {
-          detailedBitDiffs[3] = detailedBitDiffs[3] + 1; // double high
-        }
+  if (!(expectedDoubleRaw == doubleRaw)) {
+    if (expectedDoubleRaw == doubleRaw + 1 ||
+        expectedDoubleRaw == doubleRaw - 1) {
+      curBitDiffs++;
+      if (expectedDoubleRaw == doubleRaw + 1) {
+        detailedBitDiffs[2] = detailedBitDiffs[2] + 1; // double low
       } else {
-        curFails++;
-      }
-      if (curFails + curBitDiffs < 10) {
-        std::cout << "Double fail for '" << num << "'. Expected " << std::hex
-                  << expectedDoubleRaw << " but got " << doubleRaw << "\n"
-                  << std::dec;
+        detailedBitDiffs[3] = detailedBitDiffs[3] + 1; // double high
       }
+    } else {
+      curFails++;
+    }
+    if (curFails + curBitDiffs < 10) {
+      LIBC_NAMESPACE::printf("Double fail for '%s'. Expected %lx but got %lx\n",
+                             num, expectedDoubleRaw, doubleRaw);
     }
   }
+}
+
+int checkBuffer(int *totalFails, int *totalBitDiffs, int *detailedBitDiffs,
+                int *total) {
+  const char *lines[6] = {"3C00 3F800000 3FF0000000000000 1",
+                          "3D00 3FA00000 3FF4000000000000 1.25",
+                          "3D9A 3FB33333 3FF6666666666666 1.4",
+                          "57B7 42F6E979 405EDD2F1A9FBE77 123.456",
+                          "622A 44454000 4088A80000000000 789",
+                          "7C00 7F800000 7FF0000000000000 123.456e789"};
+
+  int32_t curFails = 0;    // Only counts actual failures, not bitdiffs.
+  int32_t curBitDiffs = 0; // A bitdiff is when the expected result and actual
+  // result are off by +/- 1 bit.
+
+  for (uint8_t i = 0; i < 6; i++) {
+    auto line = const_cast<char *>(lines[i]);
+    parseLine(line, total, detailedBitDiffs, curFails, curBitDiffs);
+  }
+
+  *totalBitDiffs += curBitDiffs;
+  *totalFails += curFails;
+
+  if (curFails > 1 || curBitDiffs > 1) {
+    return 2;
+  }
+  return 0;
+}
 
-  fileStream.close();
+int checkFile(char *inputFileName, int *totalFails, int *totalBitDiffs,
----------------
mikhailramalho wrote:

Got it, but if the goal is to run it manually on large files, can we remove the file from the repo and keep the static data for the automated test?

If so, you can ignore my comments to remove the file handling stuff @bassiounix 



https://github.com/llvm/llvm-project/pull/133978


More information about the libc-commits mailing list