inline new high precision implementation
This commit is contained in:
@@ -2,61 +2,21 @@
|
||||
#include "ns3/fatal-error.h"
|
||||
#include <math.h>
|
||||
|
||||
#define MAX_64 18446744073709551615.0
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
HighPrecision::HighPrecision ()
|
||||
: m_value (0)
|
||||
{}
|
||||
HighPrecision::HighPrecision (int64_t value, bool dummy)
|
||||
: m_value (value)
|
||||
{
|
||||
m_value <<= 64;
|
||||
}
|
||||
#define HP128_MAX_64 18446744073709551615.0
|
||||
|
||||
HighPrecision::HighPrecision (double value)
|
||||
{
|
||||
bool is_negative = value < 0;
|
||||
value = is_negative?-value:value;
|
||||
double hi = floor (value);
|
||||
double lo = (value - hi) * MAX_64;
|
||||
double lo = (value - hi) * HP128_MAX_64;
|
||||
m_value = hi;
|
||||
m_value <<= 64;
|
||||
m_value += lo;
|
||||
m_value = is_negative?-m_value:m_value;
|
||||
}
|
||||
|
||||
int64_t HighPrecision::GetInteger (void) const
|
||||
{
|
||||
int128_t v = m_value >> 64;
|
||||
return v;
|
||||
}
|
||||
double
|
||||
HighPrecision::GetDouble (void) const
|
||||
{
|
||||
bool is_negative = m_value < 0;
|
||||
uint128_t value = is_negative ? -m_value:m_value;
|
||||
uint64_t hi = value >> 64;
|
||||
uint64_t lo = value;
|
||||
double flo = lo;
|
||||
flo /= MAX_64;
|
||||
double retval = hi;
|
||||
retval += flo;
|
||||
retval = is_negative ? -retval : retval;
|
||||
return retval;
|
||||
}
|
||||
bool
|
||||
HighPrecision::Add (HighPrecision const &o)
|
||||
{
|
||||
m_value += o.m_value;
|
||||
return true;
|
||||
}
|
||||
bool
|
||||
HighPrecision::Sub (HighPrecision const &o)
|
||||
{
|
||||
m_value -= o.m_value;
|
||||
return true;
|
||||
}
|
||||
#define MASK_LO ((((uint128_t)1)<<64)-1)
|
||||
#define MASK_HI (~MASK_LO)
|
||||
bool
|
||||
@@ -141,16 +101,4 @@ HighPrecision::Div (HighPrecision const &o)
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
HighPrecision::Compare (HighPrecision const &o) const
|
||||
{
|
||||
return (m_value < o.m_value)?-1:(m_value == o.m_value)?0:1;
|
||||
}
|
||||
|
||||
HighPrecision
|
||||
HighPrecision::Zero (void)
|
||||
{
|
||||
return HighPrecision ();
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -28,31 +28,90 @@ typedef __uint128_t uint128_t;
|
||||
typedef __int128_t int128_t;
|
||||
#endif
|
||||
|
||||
//#define HP_INLINE inline
|
||||
#define HP_INLINE
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class HighPrecision
|
||||
{
|
||||
public:
|
||||
HP_INLINE HighPrecision ();
|
||||
HP_INLINE HighPrecision (int64_t value, bool dummy);
|
||||
HP_INLINE HighPrecision (double value);
|
||||
inline HighPrecision ();
|
||||
inline HighPrecision (int64_t value, bool dummy);
|
||||
HighPrecision (double value);
|
||||
|
||||
HP_INLINE int64_t GetInteger (void) const;
|
||||
HP_INLINE double GetDouble (void) const;
|
||||
HP_INLINE bool Add (HighPrecision const &o);
|
||||
HP_INLINE bool Sub (HighPrecision const &o);
|
||||
HP_INLINE bool Mul (HighPrecision const &o);
|
||||
HP_INLINE bool Div (HighPrecision const &o);
|
||||
inline int64_t GetInteger (void) const;
|
||||
inline double GetDouble (void) const;
|
||||
inline bool Add (HighPrecision const &o);
|
||||
inline bool Sub (HighPrecision const &o);
|
||||
bool Mul (HighPrecision const &o);
|
||||
bool Div (HighPrecision const &o);
|
||||
|
||||
HP_INLINE int Compare (HighPrecision const &o) const;
|
||||
HP_INLINE static HighPrecision Zero (void);
|
||||
inline int Compare (HighPrecision const &o) const;
|
||||
inline static HighPrecision Zero (void);
|
||||
private:
|
||||
int128_t m_value;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
HighPrecision::HighPrecision ()
|
||||
: m_value (0)
|
||||
{}
|
||||
HighPrecision::HighPrecision (int64_t value, bool dummy)
|
||||
: m_value (value)
|
||||
{
|
||||
m_value <<= 64;
|
||||
}
|
||||
|
||||
|
||||
double
|
||||
HighPrecision::GetDouble (void) const
|
||||
{
|
||||
#define HP128_MAX_64 18446744073709551615.0
|
||||
bool is_negative = m_value < 0;
|
||||
uint128_t value = is_negative ? -m_value:m_value;
|
||||
uint64_t hi = value >> 64;
|
||||
uint64_t lo = value;
|
||||
double flo = lo;
|
||||
flo /= HP128_MAX_64;
|
||||
double retval = hi;
|
||||
retval += flo;
|
||||
retval = is_negative ? -retval : retval;
|
||||
return retval;
|
||||
#undef HP128_MAX_64
|
||||
}
|
||||
|
||||
int64_t HighPrecision::GetInteger (void) const
|
||||
{
|
||||
int128_t v = m_value >> 64;
|
||||
return v;
|
||||
}
|
||||
|
||||
bool
|
||||
HighPrecision::Add (HighPrecision const &o)
|
||||
{
|
||||
m_value += o.m_value;
|
||||
return true;
|
||||
}
|
||||
bool
|
||||
HighPrecision::Sub (HighPrecision const &o)
|
||||
{
|
||||
m_value -= o.m_value;
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
HighPrecision::Compare (HighPrecision const &o) const
|
||||
{
|
||||
return (m_value < o.m_value)?-1:(m_value == o.m_value)?0:1;
|
||||
}
|
||||
|
||||
HighPrecision
|
||||
HighPrecision::Zero (void)
|
||||
{
|
||||
return HighPrecision ();
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* HIGH_PRECISION_128_H */
|
||||
|
||||
Reference in New Issue
Block a user