diff options
author | elliott_c <ocielliottc@users.noreply.github.com> | 2007-01-31 19:04:39 +0000 |
---|---|---|
committer | elliott_c <ocielliottc@users.noreply.github.com> | 2007-01-31 19:04:39 +0000 |
commit | 8110441969cc430b1237a4027aeeecb30cba4801 (patch) | |
tree | b8760292b42947418b364d03203a090fb7407828 | |
parent | 05b470b47454fd37d6ff806d18bbc3e1ea7a0375 (diff) | |
download | ATCD-8110441969cc430b1237a4027aeeecb30cba4801.tar.gz |
ChangeLogTag: Wed Jan 31 19:03:37 UTC 2007 Chad Elliott <elliott_c@ociweb.com>
-rw-r--r-- | ACE/ChangeLog | 28 | ||||
-rw-r--r-- | ACE/ace/Basic_Types.h | 2 | ||||
-rw-r--r-- | ACE/ace/CDR_Base.cpp | 160 | ||||
-rw-r--r-- | ACE/ace/CDR_Base.h | 53 | ||||
-rw-r--r-- | ACE/bin/tao_orb_tests.lst | 1 |
5 files changed, 243 insertions, 1 deletions
diff --git a/ACE/ChangeLog b/ACE/ChangeLog index f5d6a7f3f42..2540adbaf9c 100644 --- a/ACE/ChangeLog +++ b/ACE/ChangeLog @@ -1,3 +1,31 @@ +Wed Jan 31 19:03:37 UTC 2007 Chad Elliott <elliott_c@ociweb.com> + + * ace/Basic_Types.h: + + Added constants ACE_FLT_MIN and ACE_DBL_MIN to provide consistency + with ACE_FLT_MAX AND ACE_DBL_MAX. + + * ace/CDR_Base.h: + * ace/CDR_Base.cpp: + + Enhanced the ACE_CDR::LongDouble class which is used on platforms + where the native long double is not 16 bytes. + + Provided operators to support multiplication, division, addition + and subtraction as well as conversion to the native long double. + + An assign() method is also provided to set the value of the + ACE_CDR::LongDouble. Since this class will be stored in a union + (if used as an IDL type), it can not have a non-trivial constructor + or assignment operator. The existing + ACE_CDR_LONG_DOUBLE_INITIALIZER macro is used to initialize the + LongDouble and a new macro, ACE_CDR_LONG_DOUBLE_ASSIGNMENT, is + used to assign to the LongDouble in a portable fashion. + + * bin/tao_orb_tests.lst: + + Added the new TAO LongDouble test. + Wed Jan 31 17:30:46 UTC 2007 Steve Huston <shuston@riverace.com> * ace/config-hpux-11.00.h: diff --git a/ACE/ace/Basic_Types.h b/ACE/ace/Basic_Types.h index 48a0becdb12..ec2ca3cc2ad 100644 --- a/ACE/ace/Basic_Types.h +++ b/ACE/ace/Basic_Types.h @@ -839,7 +839,9 @@ ACE_END_VERSIONED_NAMESPACE_DECL #define ACE_UINT64_MAX ACE_UINT64_LITERAL(0xFFFFFFFFFFFFFFFF) // These use ANSI/IEEE format. #define ACE_FLT_MAX 3.402823466e+38F +#define ACE_FLT_MIN 1.175494351e-38F #define ACE_DBL_MAX 1.7976931348623158e+308 +#define ACE_DBL_MIN 2.2250738585072014e-308 # if defined (__ACE_INLINE__) # include "ace/Basic_Types.inl" diff --git a/ACE/ace/CDR_Base.cpp b/ACE/ace/CDR_Base.cpp index 8b051985eba..6be30a21b8c 100644 --- a/ACE/ace/CDR_Base.cpp +++ b/ACE/ace/CDR_Base.cpp @@ -14,6 +14,11 @@ ACE_RCSID (ace, ACE_BEGIN_VERSIONED_NAMESPACE_DECL +#if defined (NONNATIVE_LONGDOUBLE) +static const ACE_INT16 max_eleven_bit = 0x3ff; +static const ACE_INT16 max_fifteen_bit = 0x3fff; +#endif /* NONNATIVE_LONGDOUBLE */ + // // See comments in CDR_Base.inl about optimization cases for swap_XX_array. // @@ -599,6 +604,85 @@ ACE_CDR::LongLong::operator!= (const ACE_CDR::LongLong &rhs) const #endif /* NONNATIVE_LONGLONG */ #if defined (NONNATIVE_LONGDOUBLE) +ACE_CDR::LongDouble& +ACE_CDR::LongDouble::assign (const ACE_CDR::LongDouble::NativeImpl& rhs) +{ + ACE_OS::memset (this->ld, 0, sizeof (this->ld)); + + if (sizeof (rhs) == 8) + { +#if defined (ACE_LITTLE_ENDIAN) + static const size_t byte_zero = 1; + static const size_t byte_one = 0; + char rhs_ptr[16]; + ACE_CDR::swap_8 (reinterpret_cast<const char*> (&rhs), rhs_ptr); +#else + static const size_t byte_zero = 0; + static const size_t byte_one = 1; + const char* rhs_ptr = reinterpret_cast<const char*> (&rhs); +#endif + ACE_INT16 sign = static_cast<ACE_INT16> ( + static_cast<signed char> (rhs_ptr[0])) & 0x8000; + ACE_INT16 exponent = ((rhs_ptr[0] & 0x7f) << 4) | + ((rhs_ptr[1] >> 4) & 0xf); + const char* exp_ptr = reinterpret_cast<const char*> (&exponent); + + // Infinity and NaN have an exponent of 0x7ff in 64-bit IEEE + if (exponent == 0x7ff) + { + exponent = 0x7fff; + } + else + { + exponent = (exponent - max_eleven_bit) + max_fifteen_bit; + } + exponent |= sign; + + // Store the sign bit and exponent + this->ld[0] = exp_ptr[byte_zero]; + this->ld[1] = exp_ptr[byte_one]; + + // Store the mantissa. In an 8 byte double, it is split by + // 4 bits (because of the 12 bits for sign and exponent), so + // we have to shift and or the rhs to get the right bytes. + size_t li = 2; + bool direction = true; + for (size_t ri = 1; ri < sizeof (rhs);) + { + if (direction) + { + this->ld[li] |= ((rhs_ptr[ri] << 4) & 0xf0); + direction = false; + ri++; + } + else + { + this->ld[li] |= ((rhs_ptr[ri] >> 4) & 0xf); + direction = true; + li++; + } + } +#if defined (ACE_LITTLE_ENDIAN) + ACE_OS::memcpy (rhs_ptr, this->ld, sizeof (this->ld)); + ACE_CDR::swap_16 (rhs_ptr, this->ld); +#endif + } + else + { + ACE_OS::memcpy(this->ld, + reinterpret_cast<const char*> (&rhs), sizeof (rhs)); + } + return *this; +} + +ACE_CDR::LongDouble& +ACE_CDR::LongDouble::assign (const ACE_CDR::LongDouble& rhs) +{ + if (this != &rhs) + *this = rhs; + return *this; +} + bool ACE_CDR::LongDouble::operator== (const ACE_CDR::LongDouble &rhs) const { @@ -611,6 +695,82 @@ ACE_CDR::LongDouble::operator!= (const ACE_CDR::LongDouble &rhs) const return ACE_OS::memcmp (this->ld, rhs.ld, 16) != 0; } +ACE_CDR::LongDouble::operator ACE_CDR::LongDouble::NativeImpl () const +{ + ACE_CDR::LongDouble::NativeImpl ret = 0.0; + char* lhs_ptr = reinterpret_cast<char*> (&ret); + + if (sizeof (ret) == 8) + { +#if defined (ACE_LITTLE_ENDIAN) + static const size_t byte_zero = 1; + static const size_t byte_one = 0; + char copy[16]; + ACE_CDR::swap_16 (this->ld, copy); +#else + static const size_t byte_zero = 0; + static const size_t byte_one = 1; + const char* copy = this->ld; +#endif + ACE_INT16 exponent = 0; + char* exp_ptr = reinterpret_cast<char*> (&exponent); + exp_ptr[byte_zero] = copy[0]; + exp_ptr[byte_one] = copy[1]; + + ACE_INT16 sign = (exponent & 0x8000); + exponent &= 0x7fff; + + // Infinity and NaN have an exponent of 0x7fff in 128-bit IEEE + if (exponent == 0x7fff) + { + exponent = 0x7ff; + } + else + { + exponent = (exponent - max_fifteen_bit) + max_eleven_bit; + } + exponent = (exponent << 4) | sign; + + // Store the sign and exponent + lhs_ptr[0] = exp_ptr[byte_zero]; + lhs_ptr[1] = exp_ptr[byte_one]; + + // Store the mantissa. In an 8 byte double, it is split by + // 4 bits (because of the 12 bits for sign and exponent), so + // we have to shift and or the rhs to get the right bytes. + size_t li = 1; + bool direction = true; + for (size_t ri = 2; li < sizeof (ret);) { + if (direction) + { + lhs_ptr[li] |= ((copy[ri] >> 4) & 0xf); + direction = false; + li++; + } + else + { + lhs_ptr[li] |= ((copy[ri] & 0xf) << 4); + direction = true; + ri++; + } + } + +#if defined (ACE_LITTLE_ENDIAN) + ACE_CDR::swap_8 (lhs_ptr, lhs_ptr); +#endif + } + else + { + ACE_OS::memcpy(lhs_ptr, this->ld, sizeof (ret)); + } + + // This bit of code is unnecessary. However, this code is + // necessary to work around a bug in the gcc 4.1.1 optimizer. + ACE_CDR::LongDouble tmp; + tmp.assign (ret); + + return ret; +} #endif /* NONNATIVE_LONGDOUBLE */ #if defined(_UNICOS) && !defined(_CRAYMPP) diff --git a/ACE/ace/CDR_Base.h b/ACE/ace/CDR_Base.h index 42541504934..3507b21c4ae 100644 --- a/ACE/ace/CDR_Base.h +++ b/ACE/ace/CDR_Base.h @@ -267,15 +267,66 @@ public: # if ACE_SIZEOF_LONG_DOUBLE == 16 typedef long double LongDouble; # define ACE_CDR_LONG_DOUBLE_INITIALIZER 0 +# define ACE_CDR_LONG_DOUBLE_ASSIGNMENT(LHS, RHS) LHS = RHS # else # define NONNATIVE_LONGDOUBLE # define ACE_CDR_LONG_DOUBLE_INITIALIZER {{0}} +# define ACE_CDR_LONG_DOUBLE_ASSIGNMENT(LHS, RHS) LHS.assign (RHS) struct ACE_Export LongDouble { + // VxWorks' compiler (gcc 2.96) gets confused by the operator long + // double, so we avoid using long double as the NativeImpl. + // Linux's x86 long double format (12 or 16 bytes) is incompatible + // with Windows, Solaris, AIX, MacOS X and HP-UX (and probably others) + // long double format (8 or 16 bytes). If you need 32-bit Linux to + // inter-operate with 64-bit Linux you will want to define this + // macro so that "long double" is used. Otherwise, do not define + // this macro. +# if defined (ACE_IMPLEMENT_WITH_NATIVE_LONGDOUBLE) || \ + (!defined (linux) && !defined (VXWORKS)) + typedef long double NativeImpl; +# else + typedef double NativeImpl; +# endif /* ACE_IMPLEMENT_WITH_NATIVE_LONGDOUBLE || (!linux && !VXWORKS) */ + char ld[16]; + + LongDouble& assign (const NativeImpl& rhs); + LongDouble& assign (const LongDouble& rhs); + bool operator== (const LongDouble &rhs) const; bool operator!= (const LongDouble &rhs) const; - // @@ also need other comparison operators. + + LongDouble& operator*= (const NativeImpl rhs) { + return this->assign (static_cast<NativeImpl> (*this) * rhs); + } + LongDouble& operator/= (const NativeImpl rhs) { + return this->assign (static_cast<NativeImpl> (*this) / rhs); + } + LongDouble& operator+= (const NativeImpl rhs) { + return this->assign (static_cast<NativeImpl> (*this) + rhs); + } + LongDouble& operator-= (const NativeImpl rhs) { + return this->assign (static_cast<NativeImpl> (*this) - rhs); + } + LongDouble& operator++ () { + return this->assign (static_cast<NativeImpl> (*this) + 1); + } + LongDouble& operator-- () { + return this->assign (static_cast<NativeImpl> (*this) - 1); + } + LongDouble operator++ (int) { + LongDouble ldv = *this; + this->assign (static_cast<NativeImpl> (*this) + 1); + return ldv; + } + LongDouble operator-- (int) { + LongDouble ldv = *this; + this->assign (static_cast<NativeImpl> (*this) - 1); + return ldv; + } + + operator NativeImpl () const; }; # endif /* ACE_SIZEOF_LONG_DOUBLE != 16 */ diff --git a/ACE/bin/tao_orb_tests.lst b/ACE/bin/tao_orb_tests.lst index 1428facae20..24f61966eb6 100644 --- a/ACE/bin/tao_orb_tests.lst +++ b/ACE/bin/tao_orb_tests.lst @@ -111,6 +111,7 @@ TAO/tests/OBV/ValueBox/run_test.pl: TAO/tests/OBV/Truncatable/run_test.pl: TAO/tests/OBV/Simple/run_test.pl: TAO/tests/Hello/run_test.pl: +TAO/tests/LongDouble/run_test.pl: TAO/tests/IPV6/run_test.pl: IPV6 TAO/tests/AlternateIIOP/run_test.pl: TAO/tests/Optimized_Connection/run_test.pl: !DISABLE_ToFix_LynxOS_x86 !ACE_FOR_TAO |