From 16e9d1b66880f5687780575333f11095afb181d9 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Thu, 12 Dec 2019 19:18:44 +0100 Subject: [PATCH 1/4] core.math: Re-enable disabled tests --- src/core/math.d | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/core/math.d b/src/core/math.d index 5b83060394..387fcb9a31 100644 --- a/src/core/math.d +++ b/src/core/math.d @@ -219,10 +219,18 @@ T toPrec(T:real)(real f) { pragma(inline, false); return f; } r = toPrec!real(d + d); r = toPrec!real(r + r); - /+ Uncomment these once compiler support has been added. enum real PIR = 0xc.90fdaa22168c235p-2; enum double PID = 0x1.921fb54442d18p+1; enum float PIF = 0x1.921fb6p+1; + static assert(toPrec!float(PIR) == PIF); + static assert(toPrec!double(PIR) == PID); + static assert(toPrec!real(PIR) == PIR); + static assert(toPrec!float(PID) == PIF); + static assert(toPrec!double(PID) == PID); + static assert(toPrec!real(PID) == PID); + static assert(toPrec!float(PIF) == PIF); + static assert(toPrec!double(PIF) == PIF); + static assert(toPrec!real(PIF) == PIF); assert(toPrec!float(PIR) == PIF); assert(toPrec!double(PIR) == PID); @@ -233,5 +241,4 @@ T toPrec(T:real)(real f) { pragma(inline, false); return f; } assert(toPrec!float(PIF) == PIF); assert(toPrec!double(PIF) == PIF); assert(toPrec!real(PIF) == PIF); - +/ } From e04df19da1f75ebb70b0862ac538cacc4e62d448 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Fri, 13 Dec 2019 15:07:22 +0100 Subject: [PATCH 2/4] core.math: Update toPrec comment to reflect how rounding is done. --- src/core/math.d | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/math.d b/src/core/math.d index 387fcb9a31..f330a490c6 100644 --- a/src/core/math.d +++ b/src/core/math.d @@ -167,9 +167,11 @@ unittest /************************************* * Round argument to a specific precision. * - * D language types specify a minimum precision, not a maximum. The - * `toPrec()` function forces rounding of the argument `f` to the - * precision of the specified floating point type `T`. + * D language types specify only a minimum precision, not a maximum. The + * `toPrec()` function forces rounding of the argument `f` to the precision + * of the specified floating point type `T`. + * The rounding mode used is inevitably target-dependent, but will be done in + * a way to maximize accuracy. In most cases, the default is round-to-nearest. * * Params: * T = precision type to round to From 0309cfd57a2f1659457c7e0450f24e000d4a1066 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Mon, 27 Apr 2020 15:58:26 +0200 Subject: [PATCH 3/4] core.math: Use internal approxEqual to allow some inaccuracies on certain hardware --- src/core/math.d | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/core/math.d b/src/core/math.d index f330a490c6..d5300cfe3a 100644 --- a/src/core/math.d +++ b/src/core/math.d @@ -221,26 +221,32 @@ T toPrec(T:real)(real f) { pragma(inline, false); return f; } r = toPrec!real(d + d); r = toPrec!real(r + r); + // Comparison tests. + bool approxEqual(T)(T lhs, T rhs) + { + return fabs((lhs - rhs) / rhs) <= 1e-2 || fabs(lhs - rhs) <= 1e-5; + } + enum real PIR = 0xc.90fdaa22168c235p-2; enum double PID = 0x1.921fb54442d18p+1; enum float PIF = 0x1.921fb6p+1; - static assert(toPrec!float(PIR) == PIF); - static assert(toPrec!double(PIR) == PID); - static assert(toPrec!real(PIR) == PIR); - static assert(toPrec!float(PID) == PIF); - static assert(toPrec!double(PID) == PID); - static assert(toPrec!real(PID) == PID); - static assert(toPrec!float(PIF) == PIF); - static assert(toPrec!double(PIF) == PIF); - static assert(toPrec!real(PIF) == PIF); - - assert(toPrec!float(PIR) == PIF); - assert(toPrec!double(PIR) == PID); - assert(toPrec!real(PIR) == PIR); - assert(toPrec!float(PID) == PIF); - assert(toPrec!double(PID) == PID); - assert(toPrec!real(PID) == PID); - assert(toPrec!float(PIF) == PIF); - assert(toPrec!double(PIF) == PIF); - assert(toPrec!real(PIF) == PIF); + static assert(approxEqual(toPrec!float(PIR), PIF)); + static assert(approxEqual(toPrec!double(PIR), PID)); + static assert(approxEqual(toPrec!real(PIR), PIR)); + static assert(approxEqual(toPrec!float(PID), PIF)); + static assert(approxEqual(toPrec!double(PID), PID)); + static assert(approxEqual(toPrec!real(PID), PID)); + static assert(approxEqual(toPrec!float(PIF), PIF)); + static assert(approxEqual(toPrec!double(PIF), PIF)); + static assert(approxEqual(toPrec!real(PIF), PIF)); + + assert(approxEqual(toPrec!float(PIR), PIF)); + assert(approxEqual(toPrec!double(PIR), PID)); + assert(approxEqual(toPrec!real(PIR), PIR)); + assert(approxEqual(toPrec!float(PID), PIF)); + assert(approxEqual(toPrec!double(PID), PID)); + assert(approxEqual(toPrec!real(PID), PID)); + assert(approxEqual(toPrec!float(PIF), PIF)); + assert(approxEqual(toPrec!double(PIF), PIF)); + assert(approxEqual(toPrec!real(PIF), PIF)); } From 57be9d117d9011ed49c4c9426528069d77819b8b Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Mon, 27 Apr 2020 15:59:04 +0200 Subject: [PATCH 4/4] core.math: Remove static linkage from toPrec instantiation tests --- src/core/math.d | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/math.d b/src/core/math.d index d5300cfe3a..8dc399e083 100644 --- a/src/core/math.d +++ b/src/core/math.d @@ -208,9 +208,10 @@ T toPrec(T:real)(real f) { pragma(inline, false); return f; } @safe unittest { - static float f = 1.1f; - static double d = 1.1; - static real r = 1.1L; + // Test all instantiations work with all combinations of float. + float f = 1.1f; + double d = 1.1; + real r = 1.1L; f = toPrec!float(f + f); f = toPrec!float(d + d); f = toPrec!float(r + r);