[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [5006] Support infinities
From: |
Greg Chicares |
Subject: |
[lmi-commits] [5006] Support infinities |
Date: |
Tue, 22 Jun 2010 13:42:43 +0000 |
Revision: 5006
http://svn.sv.gnu.org/viewvc/?view=rev&root=lmi&revision=5006
Author: chicares
Date: 2010-06-22 13:42:42 +0000 (Tue, 22 Jun 2010)
Log Message:
-----------
Support infinities
Modified Paths:
--------------
lmi/trunk/ieee754.hpp
lmi/trunk/ieee754_test.cpp
Modified: lmi/trunk/ieee754.hpp
===================================================================
--- lmi/trunk/ieee754.hpp 2010-06-22 01:07:19 UTC (rev 5005)
+++ lmi/trunk/ieee754.hpp 2010-06-22 13:42:42 UTC (rev 5006)
@@ -35,8 +35,7 @@
#include <limits>
-/// Quiet NaN on IEC559-conforming implementations; otherwise, an
-/// implausible value, optionally specified.
+/// Quiet NaN if available; else a slightly less implausible value.
///
/// It is sometimes profitable to initialize a floating-point variable
/// to a recognizably implausible value. A quiet NaN is generally the
@@ -74,5 +73,60 @@
#endif // !defined __BORLANDC__
}
+/// Return positive infinity.
+///
+/// Preconditions: T is a floating-point type that has an infinity.
+///
+/// Throws if any precondition is violated.
+///
+/// Rationale: std::numeric_limits<T>::infinity() silently returns
+/// zero if T has no infinity [18.2.1.5/1]; this function throws in
+/// that case to prevent surprises.
+///
+/// Static variables are volatile if initializing them might trigger a
+/// hardware exception.
+
+template<typename T>
+inline T infinity()
+{
+ BOOST_STATIC_ASSERT(::boost::is_float<T>::value);
+ BOOST_STATIC_ASSERT(std::numeric_limits<T>::has_infinity);
+ static T const volatile z = std::numeric_limits<T>::infinity();
+ return z;
+}
+
+/// Ascertain whether argument is infinite.
+///
+/// Preconditions: T is a floating-point type. (It need not have an
+/// infinity.)
+///
+/// Throws if any precondition is violated.
+///
+/// Eventually, the C++ standard library will provide std::isinf<T>(),
+/// which might replace this implementation when compilers support it.
+///
+/// Static variables are volatile if initializing them might trigger a
+/// hardware exception.
+///
+/// The present implementation compares the argument to positive and
+/// negative infinity, if infinity is available: it doesn't seem too
+/// outrageous to presume that infinity is negatable and that its
+/// positive and negative representations are unique. Alternatively,
+/// these conditions might be tested:
+/// std::numeric_limits<T>::max() < argument
+/// argument < -std::numeric_limits<T>::max()
+/// but it doesn't seem any safer to assume that would work better on
+/// a machine that doesn't conform to IEEE 754.
+
+template<typename T>
+inline bool is_infinite(T t)
+{
+ BOOST_STATIC_ASSERT(::boost::is_float<T>::value);
+ static T const volatile pos_inf = std::numeric_limits<T>::infinity();
+ static T const volatile neg_inf = -std::numeric_limits<T>::infinity();
+ static bool const has_inf = std::numeric_limits<T>::has_infinity;
+ return has_inf && (pos_inf == t || neg_inf == t);
+}
+
#endif // ieee754_hpp
Modified: lmi/trunk/ieee754_test.cpp
===================================================================
--- lmi/trunk/ieee754_test.cpp 2010-06-22 01:07:19 UTC (rev 5005)
+++ lmi/trunk/ieee754_test.cpp 2010-06-22 13:42:42 UTC (rev 5006)
@@ -1,4 +1,4 @@
-// IEEE 754 esoterica.
+// IEEE 754 esoterica--unit test.
//
// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Gregory W. Chicares.
//
@@ -34,6 +34,24 @@
int test_main(int, char*[])
{
+ BOOST_TEST(is_infinite(infinity<float >()));
+ BOOST_TEST(is_infinite(infinity<double >()));
+ BOOST_TEST(is_infinite(infinity<long double>()));
+
+ BOOST_TEST(is_infinite<float >(-infinity<float >()));
+ BOOST_TEST(is_infinite<float >(-infinity<double >()));
+ BOOST_TEST(is_infinite<float >(-infinity<long double>()));
+ BOOST_TEST(is_infinite<double >(-infinity<float >()));
+ BOOST_TEST(is_infinite<double >(-infinity<double >()));
+ BOOST_TEST(is_infinite<double >(-infinity<long double>()));
+ BOOST_TEST(is_infinite<long double>(-infinity<float >()));
+ BOOST_TEST(is_infinite<long double>(-infinity<double >()));
+ BOOST_TEST(is_infinite<long double>(-infinity<long double>()));
+
+ BOOST_TEST(!is_infinite(0.0));
+ BOOST_TEST(!is_infinite( std::numeric_limits<double>::max()));
+ BOOST_TEST(!is_infinite(-std::numeric_limits<double>::max()));
+
if(std::numeric_limits<double>::has_quiet_NaN)
{
std::cerr << "has quiet NaN" << std::endl;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [lmi-commits] [5006] Support infinities,
Greg Chicares <=