|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r73580 - in sandbox/e_float: boost/e_float libs/e_float/src/e_float/efx libs/e_float/src/e_float/gmp libs/e_float/src/e_float/mpfr libs/e_float/test/real/cases libs/e_float/test/spot
From: e_float_at_[hidden]
Date: 2011-08-06 15:37:27
Author: christopher_kormanyos
Date: 2011-08-06 15:37:26 EDT (Sat, 06 Aug 2011)
New Revision: 73580
URL: http://svn.boost.org/trac/boost/changeset/73580
Log:
- Construct of floating-point 0.0 corrected.
- Test cases added.
- Erroneous construction from double re-corrected.
Text files modified:
sandbox/e_float/boost/e_float/e_float_base.hpp | 57 +++++++++
sandbox/e_float/boost/e_float/e_float_gmp.hpp | 6
sandbox/e_float/libs/e_float/src/e_float/efx/e_float_efx.cpp | 169 ++++++--------------------
sandbox/e_float/libs/e_float/src/e_float/gmp/e_float_gmp.cpp | 253 ++++++++++++++++++++++++++++++++-------
sandbox/e_float/libs/e_float/src/e_float/mpfr/e_float_mpfr.cpp | 38 +++++
sandbox/e_float/libs/e_float/test/real/cases/test_case_0000z_global_ops_pod.cpp | 35 +++-
sandbox/e_float/libs/e_float/test/spot/test_spot.cpp | 10 -
7 files changed, 370 insertions(+), 198 deletions(-)
Modified: sandbox/e_float/boost/e_float/e_float_base.hpp
==============================================================================
--- sandbox/e_float/boost/e_float/e_float_base.hpp (original)
+++ sandbox/e_float/boost/e_float/e_float_base.hpp 2011-08-06 15:37:26 EDT (Sat, 06 Aug 2011)
@@ -18,7 +18,9 @@
#endif
#include <iostream>
+ #include <limits>
#include <string>
+ #include <cmath>
#include <e_float/e_float_types.hpp>
@@ -174,6 +176,61 @@
static bool char_is_nonzero_predicate(const char& c) { return (c != static_cast<char>('0')); }
+ // Emphasize: This template class can be used with native floating-point
+ // types like float, double and long double. Note: For long double,
+ // you need to verify that the mantissa fits in unsigned long long.
+ template<typename native_float_type>
+ class native_float_parts
+ {
+ public:
+ native_float_parts(const native_float_type f) : u(0uLL), e(0) { make_parts(f); }
+
+ const unsigned long long& get_mantissa(void) const { return u; }
+ const int& get_exponent(void) const { return e; }
+
+ private:
+ native_float_parts(const native_float_parts&);
+ const native_float_parts& operator=(const native_float_parts&);
+
+ unsigned long long u;
+ int e;
+
+ native_float_parts();
+
+ void make_parts(const native_float_type f)
+ {
+ // Get the fraction and base-2 exponent.
+ native_float_type man = ::frexp(f, &e);
+
+ UINT32 n2 = 0u;
+
+ for(UINT32 i = static_cast<UINT32>(0u); i < static_cast<UINT32>(std::numeric_limits<native_float_type>::digits); i++)
+ {
+ // Extract the mantissa of the floating-point type in base-2
+ // (yes, one bit at a time) and store it in an unsigned long long.
+ // TBD: Is this really portable?
+ man *= 2;
+
+ n2 = static_cast<UINT32>(man);
+ man -= static_cast<native_float_type>(n2);
+
+ if(n2 != static_cast<UINT32>(0u))
+ {
+ u |= 1u;
+ }
+
+ if(i < static_cast<UINT32>(std::numeric_limits<native_float_type>::digits - 1))
+ {
+ u <<= 1u;
+ }
+ }
+
+ // Ensure that the value is normalized and adjust the exponent.
+ u |= static_cast<unsigned long long>(1uLL << (std::numeric_limits<native_float_type>::digits - 1));
+ e -= 1;
+ }
+ };
+
private:
static bool digits_match_lib_dll_is_ok;
Modified: sandbox/e_float/boost/e_float/e_float_gmp.hpp
==============================================================================
--- sandbox/e_float/boost/e_float/e_float_gmp.hpp (original)
+++ sandbox/e_float/boost/e_float/e_float_gmp.hpp 2011-08-06 15:37:26 EDT (Sat, 06 Aug 2011)
@@ -136,9 +136,9 @@
virtual e_float& calculate_sqrt(void);
// Comparison functions
- virtual bool isnan (void) const { return fpclass == ef_NaN; }
- virtual bool isinf (void) const { return fpclass == ef_inf; }
- virtual bool isfinite(void) const { return fpclass == ef_finite; }
+ virtual bool isnan (void) const { return (fpclass == ef_NaN); }
+ virtual bool isinf (void) const { return (fpclass == ef_inf); }
+ virtual bool isfinite(void) const { return (fpclass == ef_finite); }
virtual bool iszero (void) const;
virtual bool isone (void) const;
Modified: sandbox/e_float/libs/e_float/src/e_float/efx/e_float_efx.cpp
==============================================================================
--- sandbox/e_float/libs/e_float/src/e_float/efx/e_float_efx.cpp (original)
+++ sandbox/e_float/libs/e_float/src/e_float/efx/e_float_efx.cpp 2011-08-06 15:37:26 EDT (Sat, 06 Aug 2011)
@@ -32,63 +32,6 @@
#include "../../utility/util_numeric_cast.h"
#include "../../utility/util_noncopyable.h"
-namespace
-{
- // Emphasize: This template class can be used with native floating-point
- // types like float, double and 10-byte long double. Note: It would need
- // to be extended for 16-byte long double because the mantissa would
- // no longer fit in UINT64.
- template<typename native_float_type>
- class native_float_parts : private Util::noncopyable
- {
- public:
- native_float_parts(const native_float_type f) : u(0uLL), e(0) { make_parts(f); }
-
- const unsigned long long& get_mantissa(void) const { return u; }
- const int& get_exponent(void) const { return e; }
-
- private:
- unsigned long long u;
- int e;
-
- native_float_parts();
-
- void make_parts(const native_float_type f)
- {
- // Get the fraction and base-2 exponent.
- native_float_type man = ::frexp(f, &e);
-
- // Express the fractional part as a UINT64.
- UINT32 n2 = 0u;
-
- for(UINT32 i = static_cast<UINT32>(0u); i < static_cast<UINT32>(std::numeric_limits<native_float_type>::digits); i++)
- {
- // Extract the mantissa of the floating-point type in base-2
- // (yes, one bit at a time) and store it in a UINT64.
- // TBD: Is this really portable?
- man *= 2;
-
- n2 = static_cast<UINT32>(man);
- man -= static_cast<native_float_type>(n2);
-
- if(n2 != static_cast<UINT32>(0u))
- {
- u |= 1u;
- }
-
- if(i < static_cast<UINT32>(std::numeric_limits<native_float_type>::digits - 1))
- {
- u <<= 1u;
- }
- }
-
- // Ensure that the value is normalized and adjust the exponent.
- u |= static_cast<unsigned long long>(1uLL << (std::numeric_limits<native_float_type>::digits - 1));
- e -= 1;
- }
- };
-}
-
efx::e_float::e_float(const char n) : data (),
exp (static_cast<INT64>(0)),
neg (std::numeric_limits<char>::is_signed ? (n < static_cast<char>(0)) : false),
@@ -203,18 +146,18 @@
fpclass (ef_finite),
prec_elem(ef_elem_number)
{
- bool b_neg;
+ const bool b_neg = (f < 0.0f);
+ if(!ef::isfinite(static_cast<double>(f)))
{
- const double d = static_cast<double>(f);
-
- b_neg = ef::isneg(d);
+ operator=(ef::isnan(static_cast<double>(f)) ? my_value_nan() : ((!b_neg) ? my_value_inf() : -my_value_inf()));
+ return;
+ }
- if(!ef::isfinite(d))
- {
- operator=(ef::isnan(d) ? my_value_nan() : ((!ef::isneg(d)) ? my_value_inf() : -my_value_inf()));
- return;
- }
+ if(f == 0.0f)
+ {
+ operator=(ef::zero());
+ return;
}
const native_float_parts<float> fb((!b_neg) ? f : -f);
@@ -227,19 +170,7 @@
// the double and multiply with the base-2 exponent.
const int p2 = fb.get_exponent() - (std::numeric_limits<float>::digits - 1);
- if(p2 == 0) { }
- else if((p2 > 0) && (p2 < 27))
- {
- mul_unsigned_long_long(static_cast<unsigned long long>(1uL << p2));
- }
- else if((p2 < 0) && (p2 > -27))
- {
- div_unsigned_long_long(static_cast<unsigned long long>(1uL << -p2));
- }
- else
- {
- operator*=(ef::pow2(static_cast<INT64>(p2)));
- }
+ if(p2 != 0) { operator*=(ef::pow2(static_cast<INT64>(p2))); }
neg = b_neg;
}
@@ -250,43 +181,33 @@
fpclass (ef_finite),
prec_elem(ef_elem_number)
{
- // Create an e_float from a double. Yes, this ctor does
- // maintain the full precision of double.
+ const bool b_neg = (d < 0.0);
if(!ef::isfinite(d))
{
- operator=(ef::isnan(d) ? my_value_nan() : ((!ef::isneg(d)) ? my_value_inf() : -my_value_inf()));
+ operator=(ef::isnan(d) ? my_value_nan() : ((!b_neg) ? my_value_inf() : -my_value_inf()));
+ return;
}
- else
+
+ if(d == 0.0)
{
- const bool b_neg = ef::isneg(d);
+ operator=(ef::zero());
+ return;
+ }
- const native_float_parts<double> db((!b_neg) ? d : -d);
+ const native_float_parts<double> db((!b_neg) ? d : -d);
- // Create an e_float from the fractional part of the
- // mantissa expressed as an unsigned long long.
- from_unsigned_long_long(db.get_mantissa());
+ // Create an e_float from the fractional part of the
+ // mantissa expressed as an unsigned long long.
+ from_unsigned_long_long(db.get_mantissa());
- // Scale the UINT64 representation to the fractional part of
- // the double and multiply with the base-2 exponent.
- const int p2 = db.get_exponent() - (std::numeric_limits<double>::digits - 1);
+ // Scale the UINT64 representation to the fractional part of
+ // the double and multiply with the base-2 exponent.
+ const int p2 = db.get_exponent() - (std::numeric_limits<double>::digits - 1);
- if(p2 == 0) { }
- else if((p2 > 0) && (p2 < 27))
- {
- mul_unsigned_long_long(static_cast<unsigned long long>(1uL << p2));
- }
- else if((p2 < 0) && (p2 > -27))
- {
- div_unsigned_long_long(static_cast<unsigned long long>(1uL << -p2));
- }
- else
- {
- operator*=(ef::pow2(static_cast<INT64>(p2)));
- }
+ if(p2 != 0) { operator*=(ef::pow2(static_cast<INT64>(p2))); }
- neg = b_neg;
- }
+ neg = b_neg;
}
efx::e_float::e_float(const long double ld) : data (),
@@ -295,18 +216,18 @@
fpclass (ef_finite),
prec_elem(ef_elem_number)
{
- bool b_neg;
+ const bool b_neg = (ld < static_cast<long double>(0.0));
+ if(!ef::isfinite(static_cast<double>(ld)))
{
- const double d = static_cast<double>(ld);
-
- b_neg = ef::isneg(d);
+ operator=(ef::isnan(static_cast<double>(ld)) ? my_value_nan() : ((!b_neg) ? my_value_inf() : -my_value_inf()));
+ return;
+ }
- if(!ef::isfinite(d))
- {
- operator=(ef::isnan(d) ? my_value_nan() : ((!ef::isneg(d)) ? my_value_inf() : -my_value_inf()));
- return;
- }
+ if(ld == static_cast<long double>(0.0))
+ {
+ operator=(ef::zero());
+ return;
}
const native_float_parts<long double> ldb((!b_neg) ? ld : -ld);
@@ -319,19 +240,7 @@
// the double and multiply with the base-2 exponent.
const int p2 = ldb.get_exponent() - (std::numeric_limits<long double>::digits - 1);
- if(p2 == 0) { }
- else if((p2 > 0) && (p2 < 27))
- {
- mul_unsigned_long_long(static_cast<unsigned long long>(1uL << p2));
- }
- else if((p2 < 0) && (p2 > -27))
- {
- div_unsigned_long_long(static_cast<unsigned long long>(1uL << -p2));
- }
- else
- {
- operator*=(ef::pow2(static_cast<INT64>(p2)));
- }
+ if(p2 != 0) { operator*=(ef::pow2(static_cast<INT64>(p2))); }
neg = b_neg;
}
@@ -909,6 +818,7 @@
}
}
+// TBD: These need overflow and underflow checks.
efx::e_float& efx::e_float::add_unsigned_long_long(const unsigned long long n) { return operator+=(e_float(n)); }
efx::e_float& efx::e_float::sub_unsigned_long_long(const unsigned long long n) { return operator-=(e_float(n)); }
@@ -947,13 +857,13 @@
if(n >= static_cast<unsigned long long>(ef_elem_mask))
{
+ neg = b_neg;
return operator*=(e_float(n));
}
if(n == static_cast<unsigned long long>(1u))
{
neg = b_neg;
-
return *this;
}
@@ -1045,6 +955,7 @@
if(n >= static_cast<unsigned long long>(ef_elem_mask))
{
+ neg = b_neg;
return operator/=(e_float(n));
}
Modified: sandbox/e_float/libs/e_float/src/e_float/gmp/e_float_gmp.cpp
==============================================================================
--- sandbox/e_float/libs/e_float/src/e_float/gmp/e_float_gmp.cpp (original)
+++ sandbox/e_float/libs/e_float/src/e_float/gmp/e_float_gmp.cpp 2011-08-06 15:37:26 EDT (Sat, 06 Aug 2011)
@@ -12,12 +12,20 @@
#include <iomanip>
#include <vector>
#include <algorithm>
+#include <cfloat>
#include <e_float/e_float.hpp>
#include <e_float/e_float_constants.hpp>
+#include <e_float/e_float_elementary.hpp>
+
#include "e_float_gmp_protos.h"
#include "../../utility/util_lexical_cast.h"
+#if defined(__GNUC__)
+ static inline INT32 _isnan (float x) { return static_cast<INT32>(std::isnan <float>(x)); }
+ static inline INT32 _finite(float x) { return static_cast<INT32>(std::isfinite<float>(x)); }
+#endif
+
namespace
{
const double& d_log2(void)
@@ -51,55 +59,129 @@
return val_min_exp2;
}
-gmp::e_float::e_float(const INT32 n) : fpclass (ef_finite),
- prec_elem(ef_digits10_tol)
+
+
+gmp::e_float::e_float() : fpclass (ef_finite),
+ prec_elem(ef_digits10_tol)
{
init();
+ ::mpf_init(rop);
+}
- const bool b_neg = (n < static_cast<INT32>(0));
+/*
+gmp::e_float::e_float(const char n);
+gmp::e_float::e_float(const wchar_t n);
+*/
- from_uint32(b_neg ? static_cast<UINT32>(-n) : static_cast<UINT32>(n));
+gmp::e_float::e_float(const signed char n) : fpclass (ef_finite),
+ prec_elem(ef_digits10_tol)
+{
+ init();
+ const bool b_neg = (n < static_cast<signed char>(0));
+ from_unsigned_long((!b_neg) ? static_cast<unsigned long>(n) : static_cast<unsigned long>(-n));
+ if(b_neg) { ::mpf_neg(rop, rop); }
+}
- if(b_neg)
- {
- ::mpf_neg(rop, rop);
- }
+gmp::e_float::e_float(const signed short n) : fpclass (ef_finite),
+ prec_elem(ef_digits10_tol)
+{
+ init();
+ const bool b_neg = (n < static_cast<signed short>(0));
+ from_unsigned_long((!b_neg) ? static_cast<unsigned long>(n) : static_cast<unsigned long>(-n));
+ if(b_neg) { ::mpf_neg(rop, rop); }
}
-gmp::e_float::e_float(const INT64 n) : fpclass (ef_finite),
- prec_elem(ef_digits10_tol)
+gmp::e_float::e_float(const signed int n) : fpclass (ef_finite),
+ prec_elem(ef_digits10_tol)
{
init();
+ const bool b_neg = (n < static_cast<signed int>(0));
+ from_unsigned_long((!b_neg) ? static_cast<unsigned long>(n) : static_cast<unsigned long>(-n));
+ if(b_neg) { ::mpf_neg(rop, rop); }
+}
- const bool b_neg = (n < static_cast<INT64>(0));
+gmp::e_float::e_float(const signed long n) : fpclass (ef_finite),
+ prec_elem(ef_digits10_tol)
+{
+ init();
+ const bool b_neg = (n < static_cast<signed long>(0));
+ from_unsigned_long((!b_neg) ? static_cast<unsigned long>(n) : static_cast<unsigned long>(-n));
+ if(b_neg) { ::mpf_neg(rop, rop); }
+}
- from_uint64(b_neg ? static_cast<UINT64>(-n) : static_cast<UINT64>(n));
+gmp::e_float::e_float(const signed long long n) : fpclass (ef_finite),
+ prec_elem(ef_digits10_tol)
+{
+ init();
+ const bool b_neg = (n < static_cast<signed long long>(0));
+ from_unsigned_long_long((!b_neg) ? static_cast<unsigned long long>(n) : static_cast<unsigned long long>(-n));
+ if(b_neg) { ::mpf_neg(rop, rop); }
+}
- if(b_neg)
- {
- ::mpf_neg(rop, rop);
- }
+gmp::e_float::e_float(const unsigned char n) : fpclass (ef_finite),
+ prec_elem(ef_digits10_tol)
+{
+ init();
+ from_unsigned_long(static_cast<unsigned long>(n));
}
-gmp::e_float::e_float(const UINT32 u) : fpclass (ef_finite),
- prec_elem(ef_digits10_tol)
+gmp::e_float::e_float(const unsigned short n) : fpclass (ef_finite),
+ prec_elem(ef_digits10_tol)
{
init();
- from_uint32(u);
+ from_unsigned_long(static_cast<unsigned long>(n));
}
-gmp::e_float::e_float(const UINT64 u) : fpclass (ef_finite),
- prec_elem(ef_digits10_tol)
+gmp::e_float::e_float(const unsigned int n) : fpclass (ef_finite),
+ prec_elem(ef_digits10_tol)
{
init();
- from_uint64(u);
+ from_unsigned_long(static_cast<unsigned long>(n));
}
-gmp::e_float::e_float() : fpclass (ef_finite),
- prec_elem(ef_digits10_tol)
+gmp::e_float::e_float(const unsigned long n) : fpclass (ef_finite),
+ prec_elem(ef_digits10_tol)
{
init();
- ::mpf_init(rop);
+ from_unsigned_long(static_cast<unsigned long>(n));
+}
+
+gmp::e_float::e_float(const unsigned long long n) : fpclass (ef_finite),
+ prec_elem(ef_digits10_tol)
+{
+ init();
+ from_unsigned_long_long(static_cast<unsigned long long>(n));
+}
+
+gmp::e_float::e_float(const float f) : fpclass (ef_finite),
+ prec_elem(ef_digits10_tol)
+{
+ init();
+
+ const bool b_neg = (f < 0.0f);
+
+ if(::_finite(f) == 0)
+ {
+ operator=(::_isnan(f) ? my_value_nan() : ((!b_neg) ? my_value_inf() : -my_value_inf()));
+ return;
+ }
+
+ const native_float_parts<float> fb((!b_neg) ? f : -f);
+
+ // Create an e_float from the fractional part of the
+ // mantissa expressed as an unsigned long long.
+ from_unsigned_long_long(fb.get_mantissa());
+
+ // Scale the UINT64 representation to the fractional part of
+ // the double and multiply with the base-2 exponent.
+ const int p2 = fb.get_exponent() - (std::numeric_limits<float>::digits - 1);
+
+ if(p2 != 0) { operator*=(ef::pow2(static_cast<INT64>(p2))); }
+
+ if(b_neg)
+ {
+ ::mpf_neg(rop, rop);
+ }
}
gmp::e_float::e_float(const double d) : fpclass (ef_finite),
@@ -109,6 +191,37 @@
::mpf_init_set_d(rop, d);
}
+gmp::e_float::e_float(const long double ld) : fpclass (ef_finite),
+ prec_elem(ef_digits10_tol)
+{
+ init();
+
+ const bool b_neg = (ld < static_cast<long double>(0.0));
+
+ if(::_finite(static_cast<double>(ld)) == 0)
+ {
+ operator=(::_isnan(static_cast<double>(ld)) ? my_value_nan() : ((!b_neg) ? my_value_inf() : -my_value_inf()));
+ return;
+ }
+
+ const native_float_parts<long double> fb((!b_neg) ? ld : -ld);
+
+ // Create an e_float from the fractional part of the
+ // mantissa expressed as an unsigned long long.
+ from_unsigned_long_long(fb.get_mantissa());
+
+ // Scale the UINT64 representation to the fractional part of
+ // the double and multiply with the base-2 exponent.
+ const int p2 = fb.get_exponent() - (std::numeric_limits<long double>::digits - 1);
+
+ if(p2 != 0) { operator*=(ef::pow2(static_cast<INT64>(p2))); }
+
+ if(b_neg)
+ {
+ ::mpf_neg(rop, rop);
+ }
+}
+
gmp::e_float::e_float(const char* const s) : fpclass (ef_finite),
prec_elem(ef_digits10_tol)
{
@@ -171,7 +284,7 @@
void gmp::e_float::from_unsigned_long_long(const unsigned long long u)
{
- if(n <= static_cast<unsigned long long>((std::numeric_limits<unsigned long>::max)()))
+ if(u <= static_cast<unsigned long long>((std::numeric_limits<unsigned long>::max)()))
{
from_unsigned_long(static_cast<unsigned long>(u));
}
@@ -321,7 +434,35 @@
return operator*=(e_float(v).calculate_inv());
}
-gmp::e_float& gmp::e_float::mul_by_int(const INT32 n)
+// TBD: This needs an overflow and underflow check.
+gmp::e_float& gmp::e_float::add_unsigned_long_long(const unsigned long long n)
+{
+ if(n <= (std::numeric_limits<unsigned long>::max)())
+ {
+ ::mpf_add_ui(rop, rop, static_cast<unsigned long>(n));
+ return *this;
+ }
+ else
+ {
+ return operator+=(e_float(n));
+ }
+}
+
+// TBD: This needs an overflow and underflow check.
+gmp::e_float& gmp::e_float::sub_unsigned_long_long(const unsigned long long n)
+{
+ if(n <= (std::numeric_limits<unsigned long>::max)())
+ {
+ ::mpf_sub_ui(rop, rop, static_cast<unsigned long>(n));
+ return *this;
+ }
+ else
+ {
+ return operator+=(e_float(n));
+ }
+}
+
+gmp::e_float& gmp::e_float::mul_unsigned_long_long(const unsigned long long n)
{
// Multiply *this with a constant signed integer.
@@ -371,7 +512,7 @@
return *this;
}
-gmp::e_float& gmp::e_float::div_by_int(const INT32 n)
+gmp::e_float& gmp::e_float::div_unsigned_long_long(const unsigned long long n)
{
const bool b_n_is_neg = (n < static_cast<INT32>(0));
@@ -547,48 +688,34 @@
const gmp::e_float& gmp::e_float::my_value_nan(void) const
{
static e_float val(0u);
-
val.fpclass = ef_NaN;
-
static const e_float qnan(val);
-
return qnan;
}
const gmp::e_float& gmp::e_float::my_value_inf(void) const
{
static e_float val(0u);
-
val.fpclass = ef_inf;
-
static const e_float inf(val);
-
return inf;
}
const gmp::e_float& gmp::e_float::my_value_max(void) const
{
static const INT64 exp10_max = std::numeric_limits<e_float>::max_exponent10;
-
static const e_float val("1E" + Util::lexical_cast(exp10_max));
-
return val;
}
const gmp::e_float& gmp::e_float::my_value_min(void) const
{
static const INT64 exp10_min = std::numeric_limits<e_float>::min_exponent10;
-
static const e_float val("1E" + Util::lexical_cast(exp10_min));
-
return val;
}
-e_float& gmp::e_float::negate(void)
-{
- ::mpf_neg(rop, rop);
- return *this;
-}
+e_float& gmp::e_float::negate(void) { ::mpf_neg(rop, rop); return *this; }
e_float& gmp::e_float::operator++(void) { ::mpf_add_ui(rop, rop, static_cast<unsigned long>(1u)); return *this; }
e_float& gmp::e_float::operator--(void) { ::mpf_sub_ui(rop, rop, static_cast<unsigned long>(1u)); return *this; }
@@ -703,7 +830,7 @@
const bool b_neg = isneg();
const e_float xx = ef::fabs(*this);
-
+
e_float nx(xx);
::mpf_floor(nx.rop, xx.rop);
@@ -721,7 +848,41 @@
return ((!b_neg) ? dx : -dx);
}
-INT64 gmp::e_float::order(void) const
+INT64 gmp::e_float::get_order_exact(void) const
+{
+ // Get the order-10 of the e_float. This is done using a partial
+ // string extraction with 10 decimal digits.
+
+ // Create a format string for 10-digits and scientific notation.
+ std::string str_fmt = std::string("%.10RNe");
+
+ // Get the ten digits.
+ std::tr1::array<char, 64u> buf = {{ static_cast<char>(0) }};
+
+ ::mpfr_sprintf(buf.data(), str_fmt.c_str(), rop);
+
+ const std::string str = std::string(buf.data());
+
+ // Extract the base-10 exponent.
+ INT64 my_exp;
+
+ const std::size_t pos_letter_e = str.rfind(static_cast<char>('e'));
+
+ if(pos_letter_e != std::string::npos)
+ {
+ std::stringstream ss;
+ ss << static_cast<const char*>(str.c_str() + (pos_letter_e + 1u));
+ ss >> my_exp;
+ }
+ else
+ {
+ my_exp = static_cast<INT64>(0);
+ }
+
+ return my_exp;
+}
+
+INT64 gmp::e_float::get_order_approximate(void) const
{
const e_float xx = ef::fabs(*this);
@@ -740,6 +901,7 @@
}
}
+/*
void gmp::e_float::wr_string(std::string& str, std::ostream& os) const
{
if(isnan())
@@ -791,6 +953,7 @@
str.insert(pos_exp, std::string(width_of_exponent_field() - width_of_exp, static_cast<char>('0')));
}
}
+*/
namespace gmp
{
Modified: sandbox/e_float/libs/e_float/src/e_float/mpfr/e_float_mpfr.cpp
==============================================================================
--- sandbox/e_float/libs/e_float/src/e_float/mpfr/e_float_mpfr.cpp (original)
+++ sandbox/e_float/libs/e_float/src/e_float/mpfr/e_float_mpfr.cpp 2011-08-06 15:37:26 EDT (Sat, 06 Aug 2011)
@@ -15,6 +15,7 @@
#include <e_float/e_float.hpp>
#include <e_float/e_float_constants.hpp>
+#include <e_float/e_float_elementary.hpp>
#include "e_float_mpfr_protos.h"
#include "../../utility/util_lexical_cast.h"
@@ -57,7 +58,42 @@
mpfr::e_float::e_float(const unsigned long n) { init(); from_unsigned_long (static_cast<unsigned long> (n)); }
mpfr::e_float::e_float(const unsigned long long n) { init(); from_unsigned_long_long(static_cast<unsigned long long>(n)); }
-mpfr::e_float::e_float(const float f) { init(); mpfr_init_set_d(rop, static_cast<double>(f), GMP_RNDN); }
+mpfr::e_float::e_float(const float f)
+{
+ init();
+
+ const bool b_neg = (f < 0.0f);
+
+ if(!ef::isfinite(static_cast<double>(f)))
+ {
+ operator=(ef::isnan(static_cast<double>(f)) ? my_value_nan() : ((!b_neg) ? my_value_inf() : -my_value_inf()));
+ return;
+ }
+
+ if(f == 0.0f)
+ {
+ mpfr_init_set_ui(rop, 0uL, GMP_RNDN);
+ return;
+ }
+
+ const native_float_parts<float> fb((!b_neg) ? f : -f);
+
+ // Create an e_float from the fractional part of the
+ // mantissa expressed as an unsigned long long.
+ from_unsigned_long_long(fb.get_mantissa());
+
+ // Scale the UINT64 representation to the fractional part of
+ // the double and multiply with the base-2 exponent.
+ const int p2 = fb.get_exponent() - (std::numeric_limits<float>::digits - 1);
+
+ if(p2 != 0) { operator*=(ef::pow2(static_cast<INT64>(p2))); }
+
+ if(b_neg)
+ {
+ ::mpfr_neg(rop, rop, GMP_RNDN);
+ }
+}
+
mpfr::e_float::e_float(const double d) { init(); mpfr_init_set_d(rop, d, GMP_RNDN); }
mpfr::e_float::e_float(const long double ld) { init(); mpfr_init_set_ld(rop, ld, GMP_RNDN); }
mpfr::e_float::e_float(const e_float& f) { init(); mpfr_init_set(rop, f.rop, GMP_RNDN); }
Modified: sandbox/e_float/libs/e_float/test/real/cases/test_case_0000z_global_ops_pod.cpp
==============================================================================
--- sandbox/e_float/libs/e_float/test/real/cases/test_case_0000z_global_ops_pod.cpp (original)
+++ sandbox/e_float/libs/e_float/test/real/cases/test_case_0000z_global_ops_pod.cpp 2011-08-06 15:37:26 EDT (Sat, 06 Aug 2011)
@@ -137,11 +137,16 @@
my_test_result &= ::e_float_equate_to::check_type<unsigned long, unsigned long long>();
my_test_result &= ::e_float_equate_to::check_type<unsigned long long, unsigned long long>();
- e_float x(123u);
+ e_float x(123u); // Initialize x with something.
- x = static_cast<float>(4.0f); my_test_result &= (x == e_float(4u));
- x = static_cast<double>(4.0); my_test_result &= (x == e_float(4u));
- x = static_cast<long double>(4.0f); my_test_result &= (x == e_float(4u));
+ // Reassign x to some floating-point POD values and check some equalities.
+ x = static_cast<float>(4.0f); my_test_result &= (x == e_float(4u));
+ x = static_cast<double>(4.0); my_test_result &= (x == e_float(4u));
+ x = static_cast<long double>(4.0); my_test_result &= (x == e_float(4u));
+
+ my_test_result &= (e_float(0.0f) == ef::zero());
+ my_test_result &= (e_float(0.0) == ef::zero());
+ my_test_result &= (e_float(static_cast<long double>(0.0)) == ef::zero());
}
};
@@ -163,13 +168,21 @@
my_test_result = true;
- my_test_result &= (ef::four() == static_cast<float>(4.0f));
- my_test_result &= (ef::four() == static_cast<double>(4.0));
- my_test_result &= (ef::four() == static_cast<long double>(4.0));
-
- my_test_result &= (ef::pi() > static_cast<float>(3.14f));
- my_test_result &= (ef::pi() > static_cast<double>(3.14));
- my_test_result &= (ef::pi() > static_cast<long double>(3.14));
+ my_test_result &= (+ef::four() == static_cast<float>(+4.0f));
+ my_test_result &= (-ef::four() == static_cast<float>(-4.0f));
+ my_test_result &= (+ef::four() == static_cast<double>(+4.0));
+ my_test_result &= (-ef::four() == static_cast<double>(-4.0));
+ my_test_result &= (+ef::four() == static_cast<long double>(+4.0));
+ my_test_result &= (-ef::four() == static_cast<long double>(-4.0));
+
+ my_test_result &= (e_float(11.1f) == e_float("11.1000003814697265625"));
+
+ my_test_result &= (+ef::pi() > static_cast<float>(+3.14f));
+ my_test_result &= (-ef::pi() < static_cast<float>(-3.14f));
+ my_test_result &= (+ef::pi() > static_cast<double>(+3.14));
+ my_test_result &= (-ef::pi() < static_cast<double>(-3.14));
+ my_test_result &= (+ef::pi() > static_cast<long double>(+3.14));
+ my_test_result &= (-ef::pi() < static_cast<long double>(-3.14));
my_test_result &= (static_cast<float> (0.5f) < ef::euler_gamma());
my_test_result &= (static_cast<double> (0.5) < ef::euler_gamma());
Modified: sandbox/e_float/libs/e_float/test/spot/test_spot.cpp
==============================================================================
--- sandbox/e_float/libs/e_float/test/spot/test_spot.cpp (original)
+++ sandbox/e_float/libs/e_float/test/spot/test_spot.cpp 2011-08-06 15:37:26 EDT (Sat, 06 Aug 2011)
@@ -18,13 +18,5 @@
void test::spot::test_spot(void)
{
- const std::streamsize original_prec = std::cout.precision(std::numeric_limits<e_float>::digits10);
-
- const e_float x = ef::sqrt(ef::euler_gamma());
- std::cout << x << std::endl;
-
- const e_float p = ef::log(ef::pi() * 100);
- std::cout << p << std::endl;
-
- std::cout.precision(original_prec);
+ std::cout << e_float(0.0) << std::endl;
}
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