|
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