yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #10890
[Branch ~yade-pkg/yade/git-trunk] Rev 3982: Revert removal of embedded floating_point_utilities_v3.
------------------------------------------------------------
revno: 3982
committer: Anton Gladky <gladky.anton@xxxxxxxxx>
timestamp: Mon 2014-05-26 10:10:59 +0200
message:
Revert removal of embedded floating_point_utilities_v3.
http://www.mail-archive.com/yade-dev@xxxxxxxxxxxxxxxxxxx/msg10200.html
added:
extra/
extra/floating_point_utilities_v3/
extra/floating_point_utilities_v3/README
extra/floating_point_utilities_v3/boost/
extra/floating_point_utilities_v3/boost/math/
extra/floating_point_utilities_v3/boost/math/detail/
extra/floating_point_utilities_v3/boost/math/detail/fp_traits.hpp
extra/floating_point_utilities_v3/boost/math/fpclassify.hpp
extra/floating_point_utilities_v3/boost/math/nonfinite_num_facets.hpp
extra/floating_point_utilities_v3/boost/math/signbit.hpp
modified:
CMakeLists.txt
--
lp:yade
https://code.launchpad.net/~yade-pkg/yade/git-trunk
Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-pkg/yade/git-trunk/+edit-subscription
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2014-05-23 13:37:50 +0000
+++ CMakeLists.txt 2014-05-26 08:10:59 +0000
@@ -88,7 +88,7 @@
# Add possibility to use local boost installation (e.g. -DLocalBoost=1.46.1)
IF ( NOT LocalBoost )
- SET(LocalBoost "1.47.0") # Minimal required Boost version
+ SET(LocalBoost "1.35.0") # Minimal required Boost version
ENDIF ( NOT LocalBoost )
FIND_PACKAGE(Boost ${LocalBoost} COMPONENTS python thread filesystem iostreams regex serialization system date_time REQUIRED)
INCLUDE_DIRECTORIES (${Boost_INCLUDE_DIRS})
@@ -330,6 +330,16 @@
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR})
#===========================================================
+# floating_point_utilities_v3 are already in Boost included
+# Use embedded copy only if Boost older than 1.47.0
+
+IF((Boost_MINOR_VERSION LESS 47) AND (Boost_MAJOR_VERSION EQUAL 1))
+ MESSAGE(STATUS "Boost version is less than 1.47, using embedded version of floating_point_utilities_v3")
+ MESSAGE(STATUS "Consider updating boost or system, as this embedded library will be removed soon")
+ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/extra/floating_point_utilities_v3)
+ENDIF((Boost_MINOR_VERSION LESS 47) AND (Boost_MAJOR_VERSION EQUAL 1))
+
+#===========================================================
IF(ENABLE_LBMFLOW)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DLBM_ENGINE")
SET(CONFIGURED_FEATS "${CONFIGURED_FEATS} LBMFLOW")
=== added directory 'extra'
=== added directory 'extra/floating_point_utilities_v3'
=== added file 'extra/floating_point_utilities_v3/README'
--- extra/floating_point_utilities_v3/README 1970-01-01 00:00:00 +0000
+++ extra/floating_point_utilities_v3/README 2014-05-26 08:10:59 +0000
@@ -0,0 +1,7 @@
+Graceful handling of nan and inf in iostream
+
+Proposed for boost::math
+
+Downloaded from: http://www.boostpro.com/vault/index.php?action=downloadfile&filename=floating_point_utilities_v3.zip&directory=Math%20-%20Numerics&
+
+stripped of documentation
=== added directory 'extra/floating_point_utilities_v3/boost'
=== added directory 'extra/floating_point_utilities_v3/boost/math'
=== added directory 'extra/floating_point_utilities_v3/boost/math/detail'
=== added file 'extra/floating_point_utilities_v3/boost/math/detail/fp_traits.hpp'
--- extra/floating_point_utilities_v3/boost/math/detail/fp_traits.hpp 1970-01-01 00:00:00 +0000
+++ extra/floating_point_utilities_v3/boost/math/detail/fp_traits.hpp 2014-05-26 08:10:59 +0000
@@ -0,0 +1,576 @@
+// fp_traits.hpp
+
+#ifndef BOOST_MATH_FP_TRAITS_HPP
+#define BOOST_MATH_FP_TRAITS_HPP
+
+// Copyright (c) 2006 Johan Rade
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if defined(__vms) && defined(__DECCXX) && !__IEEE_FLOAT
+# error The VAX floating point mode on VMS is not supported.
+#endif
+
+#include <cstring>
+
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/detail/endian.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_floating_point.hpp>
+
+//------------------------------------------------------------------------------
+
+namespace boost {
+namespace math {
+namespace detail {
+
+//------------------------------------------------------------------------------
+
+/*
+Most processors support three different floating point precisions:
+single precision (32 bits), double precision (64 bits)
+and extended double precision (>64 bits)
+
+Note that the C++ type long double can be implemented
+both as double precision and extended double precision.
+*/
+
+struct single_precision_tag {};
+struct double_precision_tag {};
+struct extended_double_precision_tag {};
+
+//------------------------------------------------------------------------------
+
+/*
+template<class T, class U> struct fp_traits_impl;
+
+ This is traits class that describes the binary structure of floating
+ point numbers of C++ type T and precision U
+
+Requirements:
+
+ T = float, double or long double
+ U = single_precision_tag, double_precision_tag
+ or extended_double_precision_tag
+
+Typedef members:
+
+ bits -- the target type when copying the leading bytes of a floating
+ point number. It is a typedef for uint32_t or uint64_t.
+
+ coverage -- tells us whether all bytes are copied or not.
+ It is a typedef for all_bits or not_all_bits.
+
+Static data members:
+
+ sign, exponent, flag, mantissa -- bit masks that give the meaning of the bits
+ in the leading bytes.
+
+Static function members:
+
+ init() -- initializes the static data members, if needed.
+ (Is a no-op in the specialized versions of the template.)
+
+ get_bits(), set_bits() -- provide access to the leading bytes.
+*/
+
+struct all_bits {};
+struct not_all_bits {};
+
+// Generic version -------------------------------------------------------------
+
+// The generic version uses run time initialization to determine the floating
+// point format. It is capable of handling most formats,
+// but not the Motorola 68K extended double precision format.
+
+// Currently the generic version is used only for extended double precision
+// on Itanium. In all other cases there are specializations of the template
+// that use compile time initialization.
+
+template<class T> struct uint32_t_coverage
+{
+ typedef not_all_bits type;
+};
+
+template<> struct uint32_t_coverage<single_precision_tag>
+{
+ typedef all_bits type;
+};
+
+template<class T, class U> struct fp_traits_impl
+{
+ typedef uint32_t bits;
+ typedef BOOST_DEDUCED_TYPENAME uint32_t_coverage<U>::type coverage;
+
+ BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
+ static uint32_t exponent;
+ static uint32_t flag;
+ static uint32_t mantissa;
+
+ static void init()
+ {
+ if(is_init_) return;
+ do_init_();
+ is_init_ = true;
+ }
+
+ static void get_bits(T x, uint32_t& a)
+ {
+ memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
+ }
+
+ static void set_bits(T& x, uint32_t a)
+ {
+ memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
+ }
+
+private:
+ static size_t offset_;
+ static bool is_init_;
+ static void do_init_();
+};
+
+//..............................................................................
+
+template<class T, class U> uint32_t fp_traits_impl<T,U>::exponent;
+template<class T, class U> uint32_t fp_traits_impl<T,U>::flag;
+template<class T, class U> uint32_t fp_traits_impl<T,U>::mantissa;
+template<class T, class U> size_t fp_traits_impl<T,U>::offset_;
+template<class T, class U> bool fp_traits_impl<T,U>::is_init_;
+
+// In a single-threaded program, do_init will be called exactly once.
+// In a multi-threaded program, do_init may be called simultaneously
+// by more then one thread. That should not be a problem.
+
+//..............................................................................
+
+template<class T, class U> void fp_traits_impl<T,U>::do_init_()
+{
+ T x = static_cast<T>(3) / static_cast<T>(4);
+ // sign bit = 0
+ // exponent: first and last bit = 0, all other bits = 1
+ // flag bit (if present) = 1
+ // mantissa: first bit = 1, all other bits = 0
+
+ uint32_t a;
+
+ for(size_t k = 0; k <= sizeof(T) - 4; ++k) {
+
+ memcpy(&a, reinterpret_cast<unsigned char*>(&x) + k, 4);
+
+ switch(a) {
+
+ case 0x3f400000: // IEEE single precision format
+
+ offset_ = k;
+ exponent = 0x7f800000;
+ flag = 0x00000000;
+ mantissa = 0x007fffff;
+ return;
+
+ case 0x3fe80000: // IEEE double precision format
+ // and PowerPC extended double precision format
+ offset_ = k;
+ exponent = 0x7ff00000;
+ flag = 0x00000000;
+ mantissa = 0x000fffff;
+ return;
+
+ case 0x3ffe0000: // Motorola extended double precision format
+
+ // Must not get here. Must be handled by specialization.
+ // To get accurate cutoff between normals and subnormals
+ // we must use the flag bit that is in the 5th byte.
+ // Otherwise this cutoff will be off by a factor 2.
+ // If we do get here, then we have failed to detect the Motorola
+ // processor at compile time.
+
+ BOOST_ASSERT(false);
+ return;
+
+ case 0x3ffe8000: // IEEE extended double precision format
+ // with 15 exponent bits
+ offset_ = k;
+ exponent = 0x7fff0000;
+ flag = 0x00000000;
+ mantissa = 0x0000ffff;
+ return;
+
+ case 0x3ffec000: // Intel extended double precision format
+
+ offset_ = k;
+ exponent = 0x7fff0000;
+ flag = 0x00008000;
+ mantissa = 0x00007fff;
+ return;
+
+ default:
+ continue;
+ }
+ }
+
+ BOOST_ASSERT(false);
+
+ // Unknown format.
+}
+
+
+// float (32 bits) -------------------------------------------------------------
+
+template<> struct fp_traits_impl<float, single_precision_tag>
+{
+ typedef uint32_t bits;
+ typedef all_bits coverage;
+
+ BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
+ BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7f800000);
+ BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
+ BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x007fffff);
+
+ static void init() {}
+ static void get_bits(float x, uint32_t& a) { memcpy(&a, &x, 4); }
+ static void set_bits(float& x, uint32_t a) { memcpy(&x, &a, 4); }
+};
+
+
+// double (64 bits) ------------------------------------------------------------
+
+#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
+
+template<> struct fp_traits_impl<double, double_precision_tag>
+{
+ typedef uint32_t bits;
+ typedef not_all_bits coverage;
+
+ BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
+ BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
+ BOOST_STATIC_CONSTANT(uint32_t, flag = 0);
+ BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x000fffff);
+
+ static void init() {}
+
+ static void get_bits(double x, uint32_t& a)
+ {
+ memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
+ }
+
+ static void set_bits(double& x, uint32_t a)
+ {
+ memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
+ }
+
+private:
+
+#if defined(BOOST_BIG_ENDIAN)
+ BOOST_STATIC_CONSTANT(int, offset_ = 0);
+#elif defined(BOOST_LITTLE_ENDIAN)
+ BOOST_STATIC_CONSTANT(int, offset_ = 4);
+#else
+ BOOST_STATIC_ASSERT(false);
+#endif
+};
+
+//..............................................................................
+
+#else
+
+template<> struct fp_traits_impl<double, double_precision_tag>
+{
+ typedef uint64_t bits;
+ typedef all_bits coverage;
+
+ static const uint64_t sign = (uint64_t)0x80000000 << 32;
+ static const uint64_t exponent = (uint64_t)0x7ff00000 << 32;
+ static const uint64_t flag = 0;
+ static const uint64_t mantissa
+ = ((uint64_t)0x000fffff << 32) + (uint64_t)0xffffffff;
+
+ static void init() {}
+ static void get_bits(double x, uint64_t& a) { memcpy(&a, &x, 8); }
+ static void set_bits(double& x, uint64_t a) { memcpy(&x, &a, 8); }
+};
+
+#endif
+
+
+// long double (64 bits) -------------------------------------------------------
+
+#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
+
+template<> struct fp_traits_impl<long double, double_precision_tag>
+{
+ typedef uint32_t bits;
+ typedef not_all_bits coverage;
+
+ BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
+ BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
+ BOOST_STATIC_CONSTANT(uint32_t, flag = 0);
+ BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x000fffff);
+
+ static void init() {}
+
+ static void get_bits(long double x, uint32_t& a)
+ {
+ memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
+ }
+
+ static void set_bits(long double& x, uint32_t a)
+ {
+ memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
+ }
+
+private:
+
+#if defined(BOOST_BIG_ENDIAN)
+ BOOST_STATIC_CONSTANT(int, offset_ = 0);
+#elif defined(BOOST_LITTLE_ENDIAN)
+ BOOST_STATIC_CONSTANT(int, offset_ = 4);
+#else
+ BOOST_STATIC_ASSERT(false);
+#endif
+};
+
+//..............................................................................
+
+#else
+
+template<> struct fp_traits_impl<long double, double_precision_tag>
+{
+ typedef uint64_t bits;
+ typedef all_bits coverage;
+
+ static const uint64_t sign = (uint64_t)0x80000000 << 32;
+ static const uint64_t exponent = (uint64_t)0x7ff00000 << 32;
+ static const uint64_t flag = 0;
+ static const uint64_t mantissa
+ = ((uint64_t)0x000fffff << 32) + (uint64_t)0xffffffff;
+
+ static void init() {}
+ static void get_bits(long double x, uint64_t& a) { memcpy(&a, &x, 8); }
+ static void set_bits(long double& x, uint64_t a) { memcpy(&x, &a, 8); }
+};
+
+#endif
+
+
+// long double (>64 bits), x86 and x64 -----------------------------------------
+
+#if defined(__i386) || defined(__i386__) || defined(_M_IX86) \
+ || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) \
+ || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)
+
+// Intel extended double precision format (80 bits)
+
+template<> struct fp_traits_impl<long double, extended_double_precision_tag>
+{
+ typedef uint32_t bits;
+ typedef not_all_bits coverage;
+
+ BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
+ BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
+ BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00008000);
+ BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x00007fff);
+
+ static void init() {}
+
+ static void get_bits(long double x, uint32_t& a)
+ {
+ memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + 6, 4);
+ }
+
+ static void set_bits(long double& x, uint32_t a)
+ {
+ memcpy(reinterpret_cast<unsigned char*>(&x) + 6, &a, 4);
+ }
+};
+
+
+// long double (>64 bits), Itanium ---------------------------------------------
+
+#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
+
+// The floating point format is unknown at compile time
+// No template specialization is provided.
+// The generic definition is used.
+
+// The Itanium supports both
+// the Intel extended double precision format (80 bits) and
+// the IEEE extended double precision format with 15 exponent bits (128 bits).
+
+
+// long double (>64 bits), PowerPC ---------------------------------------------
+
+#elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) \
+ || defined(__ppc) || defined(__ppc__) || defined(__PPC__)
+
+// PowerPC extended double precision format (128 bits)
+
+template<> struct fp_traits_impl<long double, extended_double_precision_tag>
+{
+ typedef uint32_t bits;
+ typedef not_all_bits coverage;
+
+ BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
+ BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
+ BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
+ BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x000fffff);
+
+ static void init() {}
+
+ static void get_bits(long double x, uint32_t& a)
+ {
+ memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
+ }
+
+ static void set_bits(long double& x, uint32_t a)
+ {
+ memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
+ }
+
+private:
+
+#if defined(BOOST_BIG_ENDIAN)
+ BOOST_STATIC_CONSTANT(int, offset_ = 0);
+#elif defined(BOOST_LITTLE_ENDIAN)
+ BOOST_STATIC_CONSTANT(int, offset_ = 12);
+#else
+ BOOST_STATIC_ASSERT(false);
+#endif
+};
+
+
+// long double (>64 bits), Motorola 68K ----------------------------------------
+
+#elif defined(__m68k) || defined(__m68k__) \
+ || defined(__mc68000) || defined(__mc68000__) \
+
+// Motorola extended double precision format (96 bits)
+
+// It is the same format as the Intel extended double precision format,
+// except that 1) it is big-endian, 2) the 3rd and 4th byte are padding, and
+// 3) the flag bit is not set for infinity
+
+template<> struct fp_traits_impl<long double, extended_double_precision_tag>
+{
+ typedef uint32_t bits;
+ typedef not_all_bits coverage;
+
+ BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
+ BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
+ BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00008000);
+ BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x00007fff);
+
+ static void init() {}
+
+ // copy 1st, 2nd, 5th and 6th byte. 3rd and 4th byte are padding.
+
+ static void get_bits(long double x, uint32_t& a)
+ {
+ memcpy(&a, &x, 2);
+ memcpy(reinterpret_cast<unsigned char*>(&a) + 2,
+ reinterpret_cast<const unsigned char*>(&x) + 4, 2);
+ }
+
+ static void set_bits(long double& x, uint32_t a)
+ {
+ memcpy(&x, &a, 2);
+ memcpy(reinterpret_cast<unsigned char*>(&x) + 4,
+ reinterpret_cast<const unsigned char*>(&a) + 2, 2);
+ }
+};
+
+
+// long double (>64 bits), All other processors --------------------------------
+
+#else
+
+// IEEE extended double precision format with 15 exponent bits (128 bits)
+
+template<> struct fp_traits_impl<long double, extended_double_precision_tag>
+{
+ typedef uint32_t bits;
+ typedef not_all_bits coverage;
+
+ BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
+ BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
+ BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
+ BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x0000ffff);
+
+ static void init() {}
+
+ static void get_bits(long double x, uint32_t& a)
+ {
+ memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
+ }
+
+ static void set_bits(long double& x, uint32_t a)
+ {
+ memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
+ }
+
+private:
+
+#if defined(BOOST_BIG_ENDIAN)
+ BOOST_STATIC_CONSTANT(int, offset_ = 0);
+#elif defined(BOOST_LITTLE_ENDIAN)
+ BOOST_STATIC_CONSTANT(int, offset_ = 12);
+#else
+ BOOST_STATIC_ASSERT(false);
+#endif
+};
+
+#endif
+
+
+//------------------------------------------------------------------------------
+
+// size_to_precision is a type switch for converting a C++ floating point type
+// to the corresponding precision type.
+
+template<int n> struct size_to_precision;
+
+template<> struct size_to_precision<4>
+{
+ typedef single_precision_tag type;
+};
+
+template<> struct size_to_precision<8>
+{
+ typedef double_precision_tag type;
+};
+
+template<> struct size_to_precision<10>
+{
+ typedef extended_double_precision_tag type;
+};
+
+template<> struct size_to_precision<12>
+{
+ typedef extended_double_precision_tag type;
+};
+
+template<> struct size_to_precision<16>
+{
+ typedef extended_double_precision_tag type;
+};
+
+// fp_traits is a type switch that selects the right fp_traits_impl
+
+template<class T> struct fp_traits
+{
+ BOOST_STATIC_ASSERT(boost::is_floating_point<T>::value);
+ typedef BOOST_DEDUCED_TYPENAME size_to_precision<sizeof(T)>::type precision;
+ typedef fp_traits_impl<T, precision> type;
+};
+
+
+//------------------------------------------------------------------------------
+
+} // namespace detail
+} // namespace math
+} // namespace boost
+
+#endif
=== added file 'extra/floating_point_utilities_v3/boost/math/fpclassify.hpp'
--- extra/floating_point_utilities_v3/boost/math/fpclassify.hpp 1970-01-01 00:00:00 +0000
+++ extra/floating_point_utilities_v3/boost/math/fpclassify.hpp 2014-05-26 08:10:59 +0000
@@ -0,0 +1,229 @@
+// fpclassify.hpp
+
+#ifndef BOOST_MATH_FPCLASSIFY_HPP
+#define BOOST_MATH_FPCLASSIFY_HPP
+
+// Copyright (c) 2006 Johan Rade
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+The following algorithm is used:
+
+ If all exponent bits, the flag bit (if there is one),
+ and all mantissa bits are 0, then the number is zero.
+
+ If all exponent bits and the flag bit (if there is one) are 0,
+ and at least one mantissa bit is 1, then the number is subnormal.
+
+ If all exponent bits are 1 and all mantissa bits are 0,
+ then the number is infinity.
+
+ If all exponent bits are 1 and at least one mantissa bit is 1,
+ then the number is a not-a-number.
+
+ Otherwise the number is normal.
+
+(Note that the binary representation of infinity
+has flag bit 0 for Motorola 68K extended double precision,
+and flag bit 1 for Intel extended double precision.)
+
+To get the bits, the four or eight most significant bytes are copied
+into an uint32_t or uint64_t and bit masks are applied.
+This covers all the exponent bits and the flag bit (if there is one),
+but not always all the mantissa bits.
+Some of the functions below have two implementations,
+depending on whether all the mantissa bits are copied or not.
+*/
+
+#include <cmath>
+
+#ifndef FP_INFINITE
+# define FP_INFINITE 0
+# define FP_NAN 1
+# define FP_NORMAL 2
+# define FP_SUBNORMAL 3
+# define FP_ZERO 4
+#endif
+
+#include "detail/fp_traits.hpp"
+
+namespace boost {
+namespace math {
+
+//------------------------------------------------------------------------------
+
+template<class T> bool (isfinite)(T x)
+{
+ typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
+ traits::init();
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a &= traits::exponent;
+ return a != traits::exponent;
+}
+
+//------------------------------------------------------------------------------
+
+template<class T> bool (isnormal)(T x)
+{
+ typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
+ traits::init();
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a &= traits::exponent | traits::flag;
+ return (a != 0) && (a < traits::exponent);
+}
+
+//------------------------------------------------------------------------------
+
+namespace detail {
+
+ template<class T> bool isinf_impl(T x, all_bits)
+ {
+ typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a &= traits::exponent | traits::mantissa;
+ return a == traits::exponent;
+ }
+
+ template<class T> bool isinf_impl(T x, not_all_bits)
+ {
+ typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a &= traits::exponent | traits::mantissa;
+ if(a != traits::exponent)
+ return false;
+
+ traits::set_bits(x,0);
+ return x == 0;
+ }
+
+} // namespace detail
+
+template<class T> bool (isinf)(T x)
+{
+ typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
+ traits::init();
+ return detail::isinf_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
+}
+
+//------------------------------------------------------------------------------
+
+namespace detail {
+
+ template<class T> bool isnan_impl(T x, all_bits)
+ {
+ typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+ traits::init();
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a &= traits::exponent | traits::mantissa;
+ return a > traits::exponent;
+ }
+
+ template<class T> bool isnan_impl(T x, not_all_bits)
+ {
+ typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+ traits::init();
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+
+ a &= traits::exponent | traits::mantissa;
+ if(a < traits::exponent)
+ return false;
+
+ a &= traits::mantissa;
+ traits::set_bits(x,a);
+ return x != 0;
+ }
+
+} // namespace detail
+
+template<class T> bool (isnan)(T x)
+{
+ typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
+ traits::init();
+ return detail::isnan_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
+}
+
+//------------------------------------------------------------------------------
+
+namespace detail {
+
+ template<class T> int fpclassify_impl(T x, all_bits)
+ {
+ typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a &= traits::exponent | traits::flag | traits::mantissa;
+
+ if(a <= traits::mantissa) {
+ if(a == 0)
+ return FP_ZERO;
+ else
+ return FP_SUBNORMAL;
+ }
+
+ if(a < traits::exponent)
+ return FP_NORMAL;
+
+ a &= traits::mantissa;
+ if(a == 0)
+ return FP_INFINITE;
+
+ return FP_NAN;
+ }
+
+ template<class T> int fpclassify_impl(T x, not_all_bits)
+ {
+ typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a &= traits::exponent | traits::flag | traits::mantissa;
+
+ if(a <= traits::mantissa) {
+ if(x == 0)
+ return FP_ZERO;
+ else
+ return FP_SUBNORMAL;
+ }
+
+ if(a < traits::exponent)
+ return FP_NORMAL;
+
+ a &= traits::mantissa;
+ traits::set_bits(x,a);
+ if(x == 0)
+ return FP_INFINITE;
+
+ return FP_NAN;
+ }
+
+} // namespace detail
+
+template<class T> int (fpclassify)(T x)
+{
+ typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
+ traits::init();
+ return detail::fpclassify_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
+}
+
+//------------------------------------------------------------------------------
+
+} // namespace math
+} // namespace boost
+
+#endif
=== added file 'extra/floating_point_utilities_v3/boost/math/nonfinite_num_facets.hpp'
--- extra/floating_point_utilities_v3/boost/math/nonfinite_num_facets.hpp 1970-01-01 00:00:00 +0000
+++ extra/floating_point_utilities_v3/boost/math/nonfinite_num_facets.hpp 2014-05-26 08:10:59 +0000
@@ -0,0 +1,475 @@
+#ifndef BOOST_MATH_NONFINITE_NUM_FACETS_HPP
+#define BOOST_MATH_NONFINITE_NUM_FACETS_HPP
+
+// Copyright (c) 2006 Johan Rade
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <cstring>
+#include <ios>
+#include <limits>
+#include <locale>
+#include "fpclassify.hpp"
+#include "signbit.hpp"
+
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable : 4127 4511 4512 4706)
+#endif
+
+namespace boost {
+namespace math {
+
+
+// flags -----------------------------------------------------------------------
+
+const int legacy = 0x1;
+const int signed_zero = 0x2;
+const int trap_infinity = 0x4;
+const int trap_nan = 0x8;
+
+
+// class nonfinite_num_put -----------------------------------------------------
+
+template<
+ class CharType,
+ class OutputIterator = std::ostreambuf_iterator<CharType>
+>
+class nonfinite_num_put : public std::num_put<CharType, OutputIterator> {
+public:
+ explicit nonfinite_num_put(int flags = 0) : flags_(flags) {}
+
+protected:
+ virtual OutputIterator do_put(
+ OutputIterator it, std::ios_base& iosb,
+ CharType fill, double val) const
+ {
+ put_and_reset_width(it, iosb, fill, val);
+ return it;
+ }
+
+ virtual OutputIterator do_put(
+ OutputIterator it, std::ios_base& iosb,
+ CharType fill, long double val) const
+ {
+ put_and_reset_width(it, iosb, fill, val);
+ return it;
+ }
+
+private:
+ template<class ValType> void put_and_reset_width(
+ OutputIterator& it, std::ios_base& iosb,
+ CharType fill, ValType val) const
+ {
+ put_impl(it, iosb, fill, val);
+ iosb.width(0);
+ }
+
+ template<class ValType> void put_impl(
+ OutputIterator& it, std::ios_base& iosb,
+ CharType fill, ValType val) const
+ {
+ switch((boost::math::fpclassify)(val)) {
+
+ case FP_INFINITE:
+ if(flags_ & trap_infinity)
+ throw std::ios_base::failure("Infinity");
+ else if((boost::math::signbit)(val))
+ put_num_and_fill(it, iosb, "-", "inf", fill);
+ else if(iosb.flags() & std::ios_base::showpos)
+ put_num_and_fill(it, iosb, "+", "inf", fill);
+ else
+ put_num_and_fill(it, iosb, "", "inf", fill);
+ break;
+
+ case FP_NAN:
+ if(flags_ & trap_nan)
+ throw std::ios_base::failure("NaN");
+ else if((boost::math::signbit)(val))
+ put_num_and_fill(it, iosb, "-", "nan", fill);
+ else if(iosb.flags() & std::ios_base::showpos)
+ put_num_and_fill(it, iosb, "+", "nan", fill);
+ else
+ put_num_and_fill(it, iosb, "", "nan", fill);
+ break;
+
+ case FP_ZERO:
+ if(flags_ & signed_zero) {
+ if((boost::math::signbit)(val))
+ put_num_and_fill(it, iosb, "-", "0", fill);
+ else if(iosb.flags() & std::ios_base::showpos)
+ put_num_and_fill(it, iosb, "+", "0", fill);
+ else
+ put_num_and_fill(it, iosb, "", "0", fill);
+ }
+ else
+ put_num_and_fill(it, iosb, "", "0", fill);
+ break;
+
+ default:
+ it = std::num_put<CharType, OutputIterator>::do_put(
+ it, iosb, fill, val);
+ break;
+ }
+ }
+
+ void put_num_and_fill(
+ OutputIterator& it, std::ios_base& iosb, const char* prefix,
+ const char* body, CharType fill) const
+ {
+ int width = (int)strlen(prefix) + (int)strlen(body);
+ std::ios_base::fmtflags adjust
+ = iosb.flags() & std::ios_base::adjustfield;
+ const std::ctype<CharType>& ct
+ = std::use_facet<std::ctype<CharType> >(iosb.getloc());
+
+ if(adjust != std::ios_base::internal && adjust != std::ios_base::left)
+ put_fill(it, iosb, fill, width);
+
+ while(*prefix)
+ *it = ct.widen(*(prefix++));
+
+ if(adjust == std::ios_base::internal)
+ put_fill(it, iosb, fill, width);
+
+ if(iosb.flags() & std::ios_base::uppercase) {
+ while(*body)
+ *it = ct.toupper(ct.widen(*(body++)));
+ }
+ else {
+ while(*body)
+ *it = ct.widen(*(body++));
+ }
+
+ if(adjust == std::ios_base::left)
+ put_fill(it, iosb, fill, width);
+ }
+
+ void put_fill(
+ OutputIterator& it, std::ios_base& iosb,
+ CharType fill, int width) const
+ {
+ for(int i = iosb.width() - width; i > 0; --i)
+ *it = fill;
+ }
+
+private:
+ const int flags_;
+};
+
+
+// class nonfinite_num_get ------------------------------------------------------
+
+template<
+ class CharType,
+ class InputIterator = std::istreambuf_iterator<CharType>
+>
+class nonfinite_num_get : public std::num_get<CharType, InputIterator> {
+public:
+ explicit nonfinite_num_get(int flags = 0) : flags_(flags) {}
+
+protected:
+ virtual InputIterator do_get(
+ InputIterator it, InputIterator end, std::ios_base& iosb,
+ std::ios_base::iostate& state, float& val) const
+ {
+ get_and_check_eof(it, end, iosb, state, val);
+ return it;
+ }
+
+ virtual InputIterator do_get(
+ InputIterator it, InputIterator end, std::ios_base& iosb,
+ std::ios_base::iostate& state, double& val) const
+ {
+ get_and_check_eof(it, end, iosb, state, val);
+ return it;
+ }
+
+ virtual InputIterator do_get(
+ InputIterator it, InputIterator end, std::ios_base& iosb,
+ std::ios_base::iostate& state, long double& val) const
+ {
+ get_and_check_eof(it, end, iosb, state, val);
+ return it;
+ }
+
+//..............................................................................
+
+private:
+ template<class ValType> static ValType positive_nan()
+ {
+ // on some platforms quiet_NaN() is negative
+ return (boost::math::copysign)(
+ std::numeric_limits<ValType>::quiet_NaN(), 1);
+ }
+
+ template<class ValType> void get_and_check_eof(
+ InputIterator& it, InputIterator end, std::ios_base& iosb,
+ std::ios_base::iostate& state, ValType& val) const
+ {
+ get_signed(it, end, iosb, state, val);
+ if(it == end)
+ state |= std::ios_base::eofbit;
+ }
+
+ template<class ValType> void get_signed(
+ InputIterator& it, InputIterator end, std::ios_base& iosb,
+ std::ios_base::iostate& state, ValType& val) const
+ {
+ const std::ctype<CharType>& ct
+ = std::use_facet<std::ctype<CharType> >(iosb.getloc());
+
+ char c = peek_char(it, end, ct);
+
+ bool negative = (c == '-');
+
+ if(negative || c == '+') {
+ ++it;
+ c = peek_char(it, end, ct);
+ if(c == '-' || c == '+') {
+ // without this check, "++5" etc would be accepted
+ state |= std::ios_base::failbit;
+ return;
+ }
+ }
+
+ get_unsigned(it, end, iosb, ct, state, val);
+
+ if(negative)
+ val = (boost::math::changesign)(val);
+ }
+
+ template<class ValType> void get_unsigned(
+ InputIterator& it, InputIterator end, std::ios_base& iosb,
+ const std::ctype<CharType>& ct,
+ std::ios_base::iostate& state, ValType& val) const
+ {
+ switch(peek_char(it, end, ct)) {
+
+ case 'i':
+ get_i(it, end, ct, state, val);
+ break;
+
+ case 'n':
+ get_n(it, end, ct, state, val);
+ break;
+
+ case 'q':
+ case 's':
+ get_q(it, end, ct, state, val);
+ break;
+
+ default:
+ it = std::num_get<CharType, InputIterator>::do_get(
+ it, end, iosb, state, val);
+ if((flags_ & legacy) && val == static_cast<ValType>(1)
+ && peek_char(it, end, ct) == '#')
+ get_one_hash(it, end, ct, state, val);
+ break;
+ }
+ }
+
+ //..........................................................................
+
+ template<class ValType> void get_i(
+ InputIterator& it, InputIterator end, const std::ctype<CharType>& ct,
+ std::ios_base::iostate& state, ValType& val) const
+ {
+ if(!std::numeric_limits<ValType>::has_infinity
+ || (flags_ & trap_infinity)) {
+ state |= std::ios_base::failbit;
+ return;
+ }
+
+ ++it;
+
+ if(!match_string(it, end, ct, "nf")) {
+ state |= std::ios_base::failbit;
+ return;
+ }
+
+ if(peek_char(it, end, ct) != 'i') {
+ val = std::numeric_limits<ValType>::infinity(); // "inf"
+ return;
+ }
+
+ ++it;
+
+ if(!match_string(it, end, ct, "nity")) {
+ state |= std::ios_base::failbit;
+ return;
+ }
+
+ val = std::numeric_limits<ValType>::infinity(); // "infinity"
+ }
+
+ template<class ValType> void get_n(
+ InputIterator& it, InputIterator end, const std::ctype<CharType>& ct,
+ std::ios_base::iostate& state, ValType& val) const
+ {
+ if(!std::numeric_limits<ValType>::has_quiet_NaN
+ || (flags_ & trap_nan)) {
+ state |= std::ios_base::failbit;
+ return;
+ }
+
+ ++it;
+
+ if(!match_string(it, end, ct, "an")) {
+ state |= std::ios_base::failbit;
+ return;
+ }
+
+ switch(peek_char(it, end, ct)) {
+ case 'q':
+ case 's':
+ if(flags_ && legacy)
+ ++it;
+ break; // "nanq", "nans"
+
+ case '(':
+ {
+ ++it;
+ char c;
+ while((c = peek_char(it, end, ct))
+ && c != ')' && c != ' ' && c != '\n' && c != '\t')
+ ++it;
+ if(c != ')') {
+ state |= std::ios_base::failbit;
+ return;
+ }
+ ++it;
+ break; // "nan(...)"
+ }
+
+ default:
+ break; // "nan"
+ }
+
+ val = positive_nan<ValType>();
+ }
+
+ template<class ValType> void get_q(
+ InputIterator& it, InputIterator end, const std::ctype<CharType>& ct,
+ std::ios_base::iostate& state, ValType& val) const
+ {
+ if(!std::numeric_limits<ValType>::has_quiet_NaN
+ || (flags_ & trap_nan) || !(flags_ & legacy)) {
+ state |= std::ios_base::failbit;
+ return;
+ }
+
+ ++it;
+
+ if(!match_string(it, end, ct, "nan")) {
+ state |= std::ios_base::failbit;
+ return;
+ }
+
+ val = positive_nan<ValType>(); // qnan, snan
+ }
+
+ template<class ValType> void get_one_hash(
+ InputIterator& it, InputIterator end, const std::ctype<CharType>& ct,
+ std::ios_base::iostate& state, ValType& val) const
+ {
+ ++it;
+
+ switch(peek_char(it, end, ct)) {
+ case 'i':
+ get_one_hash_i(it, end, ct, state, val);
+ return;
+
+ case 'q':
+ case 's':
+ if(std::numeric_limits<ValType>::has_quiet_NaN
+ && !(flags_ & trap_nan)) {
+ ++it;
+ if(match_string(it, end, ct, "nan")) {
+ // "1.#QNAN", "1.#SNAN"
+ ++it;
+ val = positive_nan<ValType>();
+ return;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ state |= std::ios_base::failbit;
+ }
+
+ template<class ValType> void get_one_hash_i(
+ InputIterator& it, InputIterator end, const std::ctype<CharType>& ct,
+ std::ios_base::iostate& state, ValType& val) const
+ {
+ ++it;
+
+ if(peek_char(it, end, ct) == 'n') {
+ ++it;
+ switch(peek_char(it, end, ct)) {
+ case 'f': // "1.#INF"
+ if(std::numeric_limits<ValType>::has_infinity
+ && !(flags_ & trap_infinity)) {
+ ++it;
+ val = std::numeric_limits<ValType>::infinity();
+ return;
+ }
+ break;
+
+ case 'd': // 1.#IND"
+ if(std::numeric_limits<ValType>::has_quiet_NaN
+ && !(flags_ & trap_nan)) {
+ ++it;
+ val = positive_nan<ValType>();
+ return;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ state |= std::ios_base::failbit;
+ }
+
+ //..........................................................................
+
+ char peek_char(
+ InputIterator& it, InputIterator end,
+ const std::ctype<CharType>& ct) const
+ {
+ if(it == end) return 0;
+ return ct.narrow(ct.tolower(*it), 0);
+ }
+
+ bool match_string(
+ InputIterator& it, InputIterator end,
+ const std::ctype<CharType>& ct, const char* s) const
+ {
+ while(it != end && *s && *s == ct.narrow(ct.tolower(*it), 0)) {
+ ++s;
+ ++it;
+ }
+ return !*s;
+ }
+
+private:
+ const int flags_;
+};
+
+//------------------------------------------------------------------------------
+
+} // namespace serialization
+} // namespace boost
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
+#endif
=== added file 'extra/floating_point_utilities_v3/boost/math/signbit.hpp'
--- extra/floating_point_utilities_v3/boost/math/signbit.hpp 1970-01-01 00:00:00 +0000
+++ extra/floating_point_utilities_v3/boost/math/signbit.hpp 2014-05-26 08:10:59 +0000
@@ -0,0 +1,86 @@
+// signbit.hpp
+
+#ifndef BOOST_MATH_SIGNBIT_HPP
+#define BOOST_MATH_SIGNBIT_HPP
+
+// Copyright (c) 2006 Johan Rade
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include "detail/fp_traits.hpp"
+
+namespace boost {
+namespace math {
+
+//------------------------------------------------------------------------------
+
+template<class T> bool (signbit)(T x)
+{
+ typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
+ traits::init();
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a &= traits::sign;
+ return a != 0;
+}
+
+//------------------------------------------------------------------------------
+
+namespace detail {
+
+ template<class T> T copysign_impl(T x, T y)
+ {
+ typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+ traits::init();
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a &= ~traits::sign;
+
+ BOOST_DEDUCED_TYPENAME traits::bits b;
+ traits::get_bits(y,b);
+ b &= traits::sign;
+
+ traits::set_bits(x,a|b);
+ return x;
+ }
+}
+
+inline float (copysign)(float x, float y) // magnitude of x and sign of y
+{
+ return detail::copysign_impl(x,y);
+}
+
+inline double (copysign)(double x, double y)
+{
+ return detail::copysign_impl(x,y);
+}
+
+inline long double (copysign)(long double x, long double y)
+{
+ return detail::copysign_impl(x,y);
+}
+
+//------------------------------------------------------------------------------
+
+template<class T> T (changesign)(T x)
+{
+ typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
+ traits::init();
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a ^= traits::sign;
+ traits::set_bits(x,a);
+ return x;
+}
+
+//------------------------------------------------------------------------------
+
+} // namespace math
+} // namespace boost
+
+#endif
Follow ups