Greetings,
I know people are mostly looking at release branch work but I'd like to
post this. Other projects like mppp and boost use our __float128 with
C++. I use it for specfun testing and various other projects. I'd like
to offer a series of patches to enable this support straight from
libstdc++. This is the first patch. Next will be <cmath> and then
<complex> a bit later.
It's pretty straightforward but others might have tips on configuration
(and anything else ;-)). Built and tested of x86_64-linux.
Ok?
Ed
2019-05-11 Ed Smith-Rowland <3dw...@verizon.net>
Implement numeric_limits<__float128>.
* include/std/limits: Copy limit macros from quadmath.h;
(__glibcxx_float128_has_denorm_loss, __glibcxx_float128_traps,
__glibcxx_float128_tinyness_before): New macros (set to false);
(numeric_limits<__float128>): New specialization.
* : Add __float128 test guarded by _GLIBCXX_USE_FLOAT128.
* : testsuite/18_support/numeric_limits/denorm_min.cc: Add __float128
test guarded by _GLIBCXX_USE_FLOAT128.
* : testsuite/18_support/numeric_limits/dr559.cc: Same.
* : testsuite/18_support/numeric_limits/epsilon.cc: Same.
* : testsuite/18_support/numeric_limits/infinity.cc: Same.
* : testsuite/18_support/numeric_limits/is_iec559.cc: Same.
* : testsuite/18_support/numeric_limits/lowest.cc: Same.
* : testsuite/18_support/numeric_limits/max_digits10.cc: Same.
* : testsuite/18_support/numeric_limits/min_max.cc: Same.
* : testsuite/18_support/numeric_limits/quiet_NaN.cc: Same.
Index: include/std/limits
===================================================================
--- include/std/limits (revision 271076)
+++ include/std/limits (working copy)
@@ -41,6 +41,19 @@
#include <bits/c++config.h>
+#if defined(_GLIBCXX_USE_FLOAT128) && !defined(__STRICT_ANSI__)
+# define FLT128_MAX 1.18973149535723176508575932662800702e4932Q
+# define FLT128_MIN 3.36210314311209350626267781732175260e-4932Q
+# define FLT128_EPSILON 1.92592994438723585305597794258492732e-34Q
+# define FLT128_DENORM_MIN 6.475175119438025110924438958227646552e-4966Q
+# define FLT128_MANT_DIG 113
+# define FLT128_MIN_EXP (-16381)
+# define FLT128_MAX_EXP 16384
+# define FLT128_DIG 33
+# define FLT128_MIN_10_EXP (-4931)
+# define FLT128_MAX_10_EXP 4932
+#endif
+
//
// The numeric_limits<> traits document implementation-defined aspects
// of fundamental arithmetic data types (integers and floating points).
@@ -123,6 +136,24 @@
# define __glibcxx_long_double_tinyness_before false
#endif
+#if defined(_GLIBCXX_USE_FLOAT128) && !defined(__STRICT_ANSI__)
+
+// __float128
+
+// Default values. Should be overridden in configuration files if necessary.
+
+# ifndef __glibcxx_float128_has_denorm_loss
+# define __glibcxx_float128_has_denorm_loss false
+# endif
+# ifndef __glibcxx_float128_traps
+# define __glibcxx_float128_traps false
+# endif
+# ifndef __glibcxx_float128_tinyness_before
+# define __glibcxx_float128_tinyness_before false
+# endif
+
+# endif // _GLIBCXX_USE_FLOAT128
+
// You should not need to define any macros below this point.
#define __glibcxx_signed_b(T,B) ((T)(-1) < 0)
@@ -1880,6 +1911,85 @@
#undef __glibcxx_long_double_traps
#undef __glibcxx_long_double_tinyness_before
+#if defined(_GLIBCXX_USE_FLOAT128) && !defined(__STRICT_ANSI__)
+
+ /// numeric_limits<__float128> specialization.
+ template<>
+ struct numeric_limits<__float128>
+ {
+ static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;
+
+ static _GLIBCXX_CONSTEXPR __float128
+ min() _GLIBCXX_USE_NOEXCEPT { return FLT128_MIN; }
+
+ static _GLIBCXX_CONSTEXPR __float128
+ max() _GLIBCXX_USE_NOEXCEPT { return FLT128_MAX; }
+
+#if __cplusplus >= 201103L
+ static _GLIBCXX_CONSTEXPR __float128
+ lowest() _GLIBCXX_USE_NOEXCEPT { return -FLT128_MAX; }
+#endif
+
+ static _GLIBCXX_USE_CONSTEXPR int digits = FLT128_MANT_DIG;
+ static _GLIBCXX_USE_CONSTEXPR int digits10 = FLT128_DIG;
+#if __cplusplus >= 201103L
+ static _GLIBCXX_USE_CONSTEXPR int max_digits10
+ = __glibcxx_max_digits10 (FLT128_MANT_DIG);
+#endif
+ static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
+ static _GLIBCXX_USE_CONSTEXPR bool is_integer = false;
+ static _GLIBCXX_USE_CONSTEXPR bool is_exact = false;
+ static _GLIBCXX_USE_CONSTEXPR int radix = __FLT_RADIX__;
+
+ static _GLIBCXX_CONSTEXPR __float128
+ epsilon() _GLIBCXX_USE_NOEXCEPT { return FLT128_EPSILON; }
+
+ static _GLIBCXX_CONSTEXPR __float128
+ round_error() _GLIBCXX_USE_NOEXCEPT { return 0.5Q; }
+
+ static _GLIBCXX_USE_CONSTEXPR int min_exponent = FLT128_MIN_EXP;
+ static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = FLT128_MIN_10_EXP;
+ static _GLIBCXX_USE_CONSTEXPR int max_exponent = FLT128_MAX_EXP;
+ static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = FLT128_MAX_10_EXP;
+
+ static _GLIBCXX_USE_CONSTEXPR bool has_infinity = true;
+ static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = true;
+ static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = has_quiet_NaN;
+ static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
+ = denorm_present;
+ static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss
+ = __glibcxx_float128_has_denorm_loss;
+
+ static _GLIBCXX_CONSTEXPR __float128
+ infinity() _GLIBCXX_USE_NOEXCEPT { return __builtin_infq(); }
+
+ static _GLIBCXX_CONSTEXPR __float128
+ quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return __builtin_nanq(""); }
+
+ static _GLIBCXX_CONSTEXPR __float128
+ signaling_NaN() _GLIBCXX_USE_NOEXCEPT { return __builtin_nansq(""); }
+
+ static _GLIBCXX_CONSTEXPR __float128
+ denorm_min() _GLIBCXX_USE_NOEXCEPT { return FLT128_DENORM_MIN; }
+
+ static _GLIBCXX_USE_CONSTEXPR bool is_iec559
+ = has_infinity && has_quiet_NaN && has_denorm == denorm_present;
+ static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
+ static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;
+
+ static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_float128_traps;
+ static _GLIBCXX_USE_CONSTEXPR bool tinyness_before
+ = __glibcxx_float128_tinyness_before;
+ static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
+ = round_to_nearest;
+ };
+
+# undef __glibcxx_float128_has_denorm_loss
+# undef __glibcxx_float128_traps
+# undef __glibcxx_float128_tinyness_before
+
+#endif // _GLIBCXX_USE_FLOAT128
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
Index: testsuite/18_support/numeric_limits/denorm_min.cc
===================================================================
--- testsuite/18_support/numeric_limits/denorm_min.cc (revision 271076)
+++ testsuite/18_support/numeric_limits/denorm_min.cc (working copy)
@@ -49,6 +49,9 @@
test_denorm_min<float>();
test_denorm_min<double>();
test_denorm_min<long double>();
+#if _GLIBCXX_USE_FLOAT128
+ test_denorm_min<__float128>();
+#endif // _GLIBCXX_USE_FLOAT128
return 0;
}
Index: testsuite/18_support/numeric_limits/dr559.cc
===================================================================
--- testsuite/18_support/numeric_limits/dr559.cc (revision 271076)
+++ testsuite/18_support/numeric_limits/dr559.cc (working copy)
@@ -105,5 +105,8 @@
do_test<float>();
do_test<double>();
do_test<long double>();
+#if _GLIBCXX_USE_FLOAT128
+ do_test<__float128>();
+#endif // _GLIBCXX_USE_FLOAT128
return 0;
}
Index: testsuite/18_support/numeric_limits/epsilon.cc
===================================================================
--- testsuite/18_support/numeric_limits/epsilon.cc (revision 271076)
+++ testsuite/18_support/numeric_limits/epsilon.cc (working copy)
@@ -41,6 +41,9 @@
test_epsilon<float>();
test_epsilon<double>();
test_epsilon<long double>();
+#if _GLIBCXX_USE_FLOAT128
+ test_epsilon<__float128>();
+#endif // _GLIBCXX_USE_FLOAT128
return 0;
}
Index: testsuite/18_support/numeric_limits/infinity.cc
===================================================================
--- testsuite/18_support/numeric_limits/infinity.cc (revision 271076)
+++ testsuite/18_support/numeric_limits/infinity.cc (working copy)
@@ -49,6 +49,9 @@
test_infinity<float>();
test_infinity<double>();
test_infinity<long double>();
+#if _GLIBCXX_USE_FLOAT128
+ test_infinity<__float128>();
+#endif // _GLIBCXX_USE_FLOAT128
return 0;
}
Index: testsuite/18_support/numeric_limits/is_iec559.cc
===================================================================
--- testsuite/18_support/numeric_limits/is_iec559.cc (revision 271076)
+++ testsuite/18_support/numeric_limits/is_iec559.cc (working copy)
@@ -69,6 +69,9 @@
test_is_iec559<float>();
test_is_iec559<double>();
test_is_iec559<long double>();
+#if _GLIBCXX_USE_FLOAT128
+ test_is_iec559<__float128>();
+#endif // _GLIBCXX_USE_FLOAT128
test04();
Index: testsuite/18_support/numeric_limits/lowest.cc
===================================================================
--- testsuite/18_support/numeric_limits/lowest.cc (revision 271076)
+++ testsuite/18_support/numeric_limits/lowest.cc (working copy)
@@ -82,6 +82,9 @@
do_test<float>();
do_test<double>();
do_test<long double>();
+#if _GLIBCXX_USE_FLOAT128
+ do_test<__float128>();
+#endif // _GLIBCXX_USE_FLOAT128
}
int main()
Index: testsuite/18_support/numeric_limits/max_digits10.cc
===================================================================
--- testsuite/18_support/numeric_limits/max_digits10.cc (revision 271076)
+++ testsuite/18_support/numeric_limits/max_digits10.cc (working copy)
@@ -65,6 +65,12 @@
const int ld_max_digits10 = (2 + std::numeric_limits<long double>::digits
* 643 / 2136);
VERIFY( std::numeric_limits<long double>::max_digits10 == ld_max_digits10 );
+
+#if _GLIBCXX_USE_FLOAT128
+ const int q_max_digits10 = (2 + std::numeric_limits<__float128>::digits
+ * 643 / 2136);
+ VERIFY( std::numeric_limits<__float128>::max_digits10 == q_max_digits10 );
+#endif // _GLIBCXX_USE_FLOAT128
}
int main()
Index: testsuite/18_support/numeric_limits/min_max.cc
===================================================================
--- testsuite/18_support/numeric_limits/min_max.cc (revision 271076)
+++ testsuite/18_support/numeric_limits/min_max.cc (working copy)
@@ -55,6 +55,9 @@
DEFINE_EXTREMA(float, FLT_MIN, FLT_MAX);
DEFINE_EXTREMA(double, DBL_MIN, DBL_MAX);
DEFINE_EXTREMA(long double, LDBL_MIN, LDBL_MAX);
+#if _GLIBCXX_USE_FLOAT128
+DEFINE_EXTREMA(__float128, FLT128_MIN, FLT128_MAX);
+#endif // _GLIBCXX_USE_FLOAT128
#undef DEFINE_EXTREMA
@@ -87,6 +90,9 @@
test_extrema<float>();
test_extrema<double>();
test_extrema<long double>();
+#if _GLIBCXX_USE_FLOAT128
+ test_extrema<__float128>();
+#endif // _GLIBCXX_USE_FLOAT128
return 0;
}
Index: testsuite/18_support/numeric_limits/quiet_NaN.cc
===================================================================
--- testsuite/18_support/numeric_limits/quiet_NaN.cc (revision 271076)
+++ testsuite/18_support/numeric_limits/quiet_NaN.cc (working copy)
@@ -49,6 +49,9 @@
test_qnan<float>();
test_qnan<double>();
test_qnan<long double>();
+#ifdef _GLIBCXX_USE_FLOAT128
+ test_qnan<__float128>();
+#endif // _GLIBCXX_USE_FLOAT128
return 0;
}