Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r53027 - in sandbox/numeric_adaptor: boost/numeric_adaptor libs/numeric_adaptor
From: barend.gehrels_at_[hidden]
Date: 2009-05-15 11:20:03


Author: barendgehrels
Date: 2009-05-15 11:20:01 EDT (Fri, 15 May 2009)
New Revision: 53027
URL: http://svn.boost.org/trac/boost/changeset/53027

Log:
Bugfix in gmp-to-string, decimal separator was not inserted
Style change in IEEE
Changed cast-to-string (but didn't help)
Changed sample to use string separately
Text files modified:
   sandbox/numeric_adaptor/boost/numeric_adaptor/cln_policy.hpp | 2
   sandbox/numeric_adaptor/boost/numeric_adaptor/gmp_policy.hpp | 21 +++++++++-
   sandbox/numeric_adaptor/boost/numeric_adaptor/ieee_policy.hpp | 12 +++---
   sandbox/numeric_adaptor/boost/numeric_adaptor/numeric_adaptor.hpp | 44 ++++++++++++++++++----
   sandbox/numeric_adaptor/libs/numeric_adaptor/sample.cpp | 79 +++++++++++++++++++++++++++++----------
   5 files changed, 121 insertions(+), 37 deletions(-)

Modified: sandbox/numeric_adaptor/boost/numeric_adaptor/cln_policy.hpp
==============================================================================
--- sandbox/numeric_adaptor/boost/numeric_adaptor/cln_policy.hpp (original)
+++ sandbox/numeric_adaptor/boost/numeric_adaptor/cln_policy.hpp 2009-05-15 11:20:01 EDT (Fri, 15 May 2009)
@@ -37,7 +37,7 @@
         // Conversions from the C built-in type `double' are provided for the
         // classes cl_DF, cl_F, cl_R, cl_N and cl_number
 
- value = cln::cl_float(v, cln::float_format(40));
+ value = cln::cl_float(v, cln::float_format(256));
     }
 
     static inline void set(type& value, std::string const& v)

Modified: sandbox/numeric_adaptor/boost/numeric_adaptor/gmp_policy.hpp
==============================================================================
--- sandbox/numeric_adaptor/boost/numeric_adaptor/gmp_policy.hpp (original)
+++ sandbox/numeric_adaptor/boost/numeric_adaptor/gmp_policy.hpp 2009-05-15 11:20:01 EDT (Fri, 15 May 2009)
@@ -12,6 +12,7 @@
 
 
 #include <string>
+#include <cstring>
 
 
 #include <gmp.h>
@@ -98,8 +99,24 @@
 
     static inline std::string as_string(type const& a)
     {
- mp_exp_t bexp;
- std::string out = mpf_get_str (0, &bexp, 10, 0, a);
+ mp_exp_t exponent;
+ static char s[1024];
+ mpf_get_str (s, &exponent, 10, sizeof(s) - 1, a);
+
+ std::string out;
+ out.reserve(100);
+
+ // TODO: this is probably not working well for large numbers -> add e0X
+
+ register int i = 0;
+ for (register const char* ptr = s; *ptr; ptr++, i++)
+ {
+ if (i == exponent)
+ {
+ out += ".";
+ }
+ out += *ptr;
+ }
         return out;
     }
 

Modified: sandbox/numeric_adaptor/boost/numeric_adaptor/ieee_policy.hpp
==============================================================================
--- sandbox/numeric_adaptor/boost/numeric_adaptor/ieee_policy.hpp (original)
+++ sandbox/numeric_adaptor/boost/numeric_adaptor/ieee_policy.hpp 2009-05-15 11:20:01 EDT (Fri, 15 May 2009)
@@ -28,16 +28,16 @@
     typedef T type;
 
     template <typename OtherType>
- static inline void set(type& value, const OtherType& v) { value = boost::numeric_cast<T>(v); }
+ static inline void set(type& value, OtherType const& v) { value = v; } //boost::numeric_cast<T>(v); }
 
- static inline void set(type& value, const std::string& v) { value = boost::lexical_cast<T>(v); }
+ static inline void set(type& value, std::string const& v) { value = boost::lexical_cast<T>(v); }
 
- static inline void sqrt(type& r, const type& a) { r = std::sqrt(a); }
- static inline void cos(type& r, const type& a) { r = std::cos(a); }
- static inline void sin(type& r, const type& a) { r = std::sin(a); }
+ static inline void sqrt(type& r, type const& a) { r = std::sqrt(a); }
+ static inline void cos(type& r, type const& a) { r = std::cos(a); }
+ static inline void sin(type& r, type const& a) { r = std::sin(a); }
 
     template <typename OtherType>
- static inline OtherType big_numeric_cast(const type& v)
+ static inline OtherType big_numeric_cast(type const& v)
     {
         return boost::numeric_cast<OtherType>(v);
     }

Modified: sandbox/numeric_adaptor/boost/numeric_adaptor/numeric_adaptor.hpp
==============================================================================
--- sandbox/numeric_adaptor/boost/numeric_adaptor/numeric_adaptor.hpp (original)
+++ sandbox/numeric_adaptor/boost/numeric_adaptor/numeric_adaptor.hpp 2009-05-15 11:20:01 EDT (Fri, 15 May 2009)
@@ -11,6 +11,40 @@
 #define NUMERIC_ADAPTOR_NUMERIC_ADAPTOR_HPP_
 
 
+
+
+template <typename Policy, typename ToType>
+struct caster
+{
+ static inline ToType cast(typename Policy::type const& value)
+ {
+ return Policy::template big_numeric_cast<ToType>(value);
+ }
+};
+
+// specialization for strings
+/*
+template <typename Policy>
+struct caster<Policy, std::string>
+{
+ static inline std::string cast(typename Policy::type const& value)
+ {
+ return Policy::as_string(value);
+ }
+};
+*/
+
+template <typename Policy>
+struct caster<Policy, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >
+{
+ static inline std::basic_string<char, std::char_traits<char>, std::allocator<char> > cast(typename Policy::type const& value)
+ {
+ return Policy::as_string(value);
+ }
+};
+
+
+
 template <typename Policy>
 struct numeric_adaptor
 {
@@ -63,17 +97,11 @@
         return *this;
     }
 
- // Cast to normal IEEE type
+ // Cast to normal IEEE type or to std::string
     template <typename ToType>
     inline operator ToType() const
     {
- return Policy::template big_numeric_cast<ToType>(value);
- }
-
- // Overload for cast to string
- inline operator std::string() const
- {
- return Policy::as_string(value);
+ return caster<Policy, ToType>::cast(value);
     }
 
 

Modified: sandbox/numeric_adaptor/libs/numeric_adaptor/sample.cpp
==============================================================================
--- sandbox/numeric_adaptor/libs/numeric_adaptor/sample.cpp (original)
+++ sandbox/numeric_adaptor/libs/numeric_adaptor/sample.cpp 2009-05-15 11:20:01 EDT (Fri, 15 May 2009)
@@ -19,32 +19,53 @@
 #endif
 
 
+
 template <typename T, typename Num>
-void sample(const std::string& header, T c1, T c2, T c4)
+void sample1(const std::string& header, T const& c1, T const& c2, T const& c4)
 {
     std::cout << std::endl << "---" << header << std::endl;
     Num v1 = c1;
     Num v2 = c2;
     Num v3 = v1 + v2;
- std::cout << T(v3);
+
+ // NOTE: strings can NOT be casted / streamed in one line for GCC/Comeau (for MSVC/DMC it is OK)
+ // See http://www.codeguru.com/forum/showthread.php?p=1842725
+ T t3 = v3;
+ std::cout << "a + b: " << t3 << std::endl;
 
     Num v4 = c4;
     Num v5 = (v1 + v2) * v4;
- std::cout << " " << T(v5);
+ T t5 = v5;
+ std::cout << " " << t5;
     v5 = v1 + v2 * v4;
- std::cout << " " << T(v5);
+ T t5a = v5;
+ std::cout << " " << t5a;
 
     Num v6 = Num::sqrt(v3);
- std::cout << " " << T(v6) << std::endl;
+ T t6 = v6;
+ std::cout << " " << t6 << std::endl;
+
+}
+
+
+
+
+template <typename T, typename Num>
+void sample2(const std::string& header, T const& c1, T const& c2, T const& c4)
+{
+ std::cout << std::endl << "---" << header << std::endl;
 
     // Conversion from int
- v6 = 4;
- std::cout << T(v6);
+ Num n = 4;
+ std::cout << T(n);
 
     // Assignment from T
- v6 = v2;
- std::cout << " " << T(v6) << std::endl;
+ Num t = c1;
+ n = t;
+ std::cout << " " << T(n) << std::endl;
 
+ Num v1 = c1;
+ Num v2 = c2;
     if (v1 > v2)
     {
         std::cout << "v1 > v2" << std::endl;
@@ -58,33 +79,51 @@
         std::cout << "v1 == v2" << std::endl;
     }
 
- Num v7 = Num::cos(v3);
+ Num v7 = Num::cos(v1);
     std::cout << "cos: " << T(v7) << std::endl;
- v7 = Num::sin(v3);
+ v7 = Num::sin(v1);
     std::cout << "sin: " << T(v7) << std::endl;
 
 }
 
+void long_double_issue()
+{
+ long double ld = 2.0000000002;
+ std::cout << "Strange: " << sizeof(long double) << " " << ld << std::endl;
+ double d = 2.0000000002;
+ std::cout << "OK: " << sizeof(double) << " " << d << std::endl;
+}
+
 
 int main()
 {
+ mpf_set_default_prec(128);
     std::cout << std::setprecision(12);
 
- double a = 2.000000000002;
- double b = 3.000000000003;
- double c = 5.000000000005;
+ long_double_issue();
+
+ sample1<std::string, numeric_adaptor<gmp_policy> >("use string, calculate with gmp",
+ "2.000000000002", "3.000000000003", "4.00000000004");
+ sample1<std::string, numeric_adaptor<cln_policy> >("use string, calculate with cln",
+ "2.000000000002", "3.000000000003", "4.00000000004");
+ sample1<double, numeric_adaptor<ieee_policy<long double> > >("use double, calculate with ieee/long double",
+ 2.0000000000002, 3.000000000003, 4.00000000004);
+
+ double a = 2.0000000002;
+ double b = 3.0000000003;
+ double c = 4.0000000004;
+
 
- sample<float, numeric_adaptor<ieee_policy<float> > >("use float, calculate with float", a, b, c);
- sample<float, numeric_adaptor<ieee_policy<double> > >("use float, calculate with double", a, b, c);
 
- sample<double, numeric_adaptor<ieee_policy<double> > >("use double, calculate with double", a, b, c);
+ sample2<float, numeric_adaptor<ieee_policy<float> > >("use float, calculate with float", a, b, c);
+ sample2<float, numeric_adaptor<ieee_policy<double> > >("use float, calculate with double", a, b, c);
+ sample2<double, numeric_adaptor<ieee_policy<double> > >("use double, calculate with double", a, b, c);
 
 #if ! defined(_MSC_VER)
- sample<double, numeric_adaptor<gmp_policy> >("use double, calculate with gmp", a, b, c);
- sample<double, numeric_adaptor<cln_policy> >("use double, calculate with CLN", a, b, c);
+ sample2<double, numeric_adaptor<gmp_policy> >("use double, calculate with gmp", a, b, c);
+ sample2<double, numeric_adaptor<cln_policy> >("use double, calculate with CLN", a, b, c);
 #endif
 
- sample<std::string, numeric_adaptor<ieee_policy<double> > >("use string, calculate with gmp","2.000000000002", "3.000000000003", "5.000000000005");
 
     return 0;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk