summaryrefslogtreecommitdiffstats
path: root/tools/slang-test/unit-test-string.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2021-06-01 16:58:07 -0400
committerGitHub <noreply@github.com>2021-06-01 16:58:07 -0400
commit7a3c87b58de2683c077bd5341052c2e3cebeb048 (patch)
tree8641667ebcfecd728bfe8b572822751fae1c55bd /tools/slang-test/unit-test-string.cpp
parent67486ee516ddc33806003727682cbfc68ab1f726 (diff)
JSONValue / Container (#1864)
* #include an absolute path didn't work - because paths were taken to always be relative. * WIP JSONWriter/JSONParser. * Checking different Layout styles for JSON. * Add slang-json-parser.h/.cpp * WIP JSONValue. * Added JSONValue::destroy/Recursive. * Improvement to JSONValue. * Improve text double conversion precision. Testing. * Simplify double parsing (just use atof). JSON comparison More testing of conversions and start of JSONValue. * Add <math.h> for isnan, isinf etc. * Small improvement with object comparison. * Fix typo in getArgsByName. * Removed use of isnan and isinf as includes don't work on linux. * Improve JSON unit test. * Added asInteger/asFloat/asBool to JSONValue. * Change comment to trigger CI build.
Diffstat (limited to 'tools/slang-test/unit-test-string.cpp')
-rw-r--r--tools/slang-test/unit-test-string.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/tools/slang-test/unit-test-string.cpp b/tools/slang-test/unit-test-string.cpp
index e27411b3e..e8a33fbbe 100644
--- a/tools/slang-test/unit-test-string.cpp
+++ b/tools/slang-test/unit-test-string.cpp
@@ -4,6 +4,10 @@
#include "test-context.h"
+//#include <math.h>
+
+#include <sstream>
+
using namespace Slang;
static bool _areEqual(const List<UnownedStringSlice>& lines, const UnownedStringSlice* checkLines, Int checkLinesCount)
@@ -43,6 +47,71 @@ static bool _checkLineParser(const UnownedStringSlice& input)
return StringUtil::extractLine(remaining, line) == false;
}
+static void _append(double v, StringBuilder& buf)
+{
+ std::ostringstream stream;
+ stream.imbue(std::locale::classic());
+ stream.setf(std::ios::fixed, std::ios::floatfield);
+ stream.precision(20);
+
+ stream << std::scientific << v;
+
+ buf << stream.str().c_str();
+}
+
+// Unit of least precision
+static int64_t _calcULPDistance(double a, double b)
+{
+ // Save work if the floats are equal.
+ // Also handles +0 == -0
+ if (a == b)
+ {
+ return 0;
+ }
+
+ const int64_t max = int64_t((~uint64_t(0)) >> 1);
+
+#if 0
+ // Max distance for NaN
+ if (isnan(a) || isnan(b))
+ {
+ return max;
+ }
+
+ // If one's infinite and they're not equal, max distance.
+ if (isinf(a) || isinf(b))
+ {
+ return max;
+ }
+#endif
+
+ int64_t ia, ib;
+ memcpy(&ia, &a, sizeof(a));
+ memcpy(&ib, &b, sizeof(b));
+
+ // Don't compare differently-signed floats.
+ if ((ia < 0) != (ib < 0))
+ {
+ return max;
+ }
+
+ // Return the absolute value of the distance in ULPs.
+ int64_t distance = ia - ib;
+ return distance < 0 ? -distance : distance;
+}
+
+static bool _areApproximatelyEqual(double a, double b, double fixedEpsilon = 1e-10, int ulpsEpsilon = 100)
+{
+ // Handle the near-zero case.
+ const double difference = abs(a - b);
+ if (difference <= fixedEpsilon)
+ {
+ return true;
+ }
+
+ return _calcULPDistance(a, b) <= ulpsEpsilon;
+}
+
static void stringUnitTest()
{
{
@@ -122,6 +191,74 @@ static void stringUnitTest()
SLANG_CHECK(checkValues.getArrayView() == ArrayView<UnownedStringSlice>(values, 3));
}
}
+ {
+
+ List<double> values;
+ values.add(0.0);
+ values.add(-0.0);
+
+ for (Index i = -300; i < 300; ++i)
+ {
+ double value = pow(10, i);
+
+ values.add(value);
+ values.add(-value);
+
+ values.addRange(value / 3);
+ values.addRange(-value / 3);
+ }
+
+ StringBuilder buf;
+
+ for (auto value : values)
+ {
+ buf.Clear();
+ _append(value, buf);
+
+ UnownedStringSlice slice = buf.getUnownedSlice();
+
+ double parsedValue;
+ SlangResult res = StringUtil::parseDouble(slice, parsedValue);
+
+ auto ulpsParsed = _calcULPDistance(value, parsedValue);
+
+ SLANG_CHECK(SLANG_SUCCEEDED(res));
+
+ // Check that they are equal
+ SLANG_CHECK(_areApproximatelyEqual(value, parsedValue));
+ }
+ }
+ {
+ List<int64_t> values;
+ values.add(0);
+
+ for (Index i = 0; i < 63; ++i)
+ {
+ auto value = int64_t(1) << i;
+
+ values.add(value);
+ values.add(-value);
+ }
+
+ StringBuilder buf;
+
+ for (auto value : values)
+ {
+ buf.Clear();
+ buf << value;
+
+
+ int64_t parsedValue;
+
+ UnownedStringSlice slice = buf.getUnownedSlice();
+ SlangResult res = StringUtil::parseInt64(slice, parsedValue);
+
+ SLANG_CHECK(SLANG_SUCCEEDED(res));
+
+ // Check that they are equal
+ SLANG_CHECK(value == parsedValue);
+ }
+ }
}
SLANG_UNIT_TEST("String", stringUnitTest);