Implement numeric_limits<__float128>.

Ed Smith-Rowland via gcc-patches gcc-patches@gcc.gnu.org
Sat May 11 02:56:00 GMT 2019


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


-------------- next part --------------
2019-05-11  Ed Smith-Rowland  <3dw4rd@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.

-------------- next part --------------
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;
 }


More information about the Gcc-patches mailing list