00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX__DOUBLE_HPP__
00014 #define __MMX__DOUBLE_HPP__
00015 #include <fenv.h>
00016 #include <basix/port.hpp>
00017
00019
00020 namespace mmx {
00021
00022
00023
00024
00025
00026 inline void set_default (double& x) { x= 0; }
00027 inline void set_nan (double& x) { x= NAN; }
00028 inline void set_maximal (double& x) { x= HUGE_VAL; }
00029 inline void set_minimal (double& x) { x= -HUGE_VAL; }
00030 inline void set_infinity (double& x) { x= HUGE_VAL; }
00031 inline void set_fuzz (double& x) { x= 0.0; }
00032 inline void set_smallest (double& x) { x= nextafter (0.0, HUGE_VAL); }
00033 inline void set_largest (double& x) { x= nextafter (HUGE_VAL, 0.0); }
00034 inline void set_accuracy (double& x) { x= __DBL_EPSILON__; }
00035 inline void set_log2 (double& x) { x= 0.6931471805599453094172321214581766L; }
00036 inline void set_pi (double& x) { x= 3.1415926535897932384626433832795029L; }
00037 inline void set_euler (double& x) { x= 0.5772156649015328606065120900824024L; }
00038 inline double times_infinity (const double& x) { return x * HUGE_VAL; }
00039
00040
00041
00042
00043
00044 inline double sqrt (const double& x) { return std::sqrt (x); }
00045 inline double exp (const double& x) { return std::exp (x); }
00046 inline double exp2 (const double& x) { return ::exp2 (x); }
00047 inline double log (const double& x) { return std::log (x); }
00048 inline double log2 (const double& x) { return ::log2 (x); }
00049 inline double cos (const double& x) { return std::cos (x); }
00050 inline double sin (const double& x) { return std::sin (x); }
00051 inline double tan (const double& x) { return std::tan (x); }
00052 inline double cosh (const double& x) { return std::cosh (x); }
00053 inline double sinh (const double& x) { return std::sinh (x); }
00054 inline double tanh (const double& x) { return std::tanh (x); }
00055 inline double acos (const double& x) { return std::acos (x); }
00056 inline double asin (const double& x) { return std::asin (x); }
00057 inline double atan (const double& x) { return std::atan (x); }
00058 inline double hypot (const double& x, const double& y) {
00059 return ::hypot (x, y); }
00060 inline double atan2 (const double& y, const double& x) {
00061 return std::atan2 (y, x); }
00062 inline double pow (const double& x, const double& y) {
00063 return std::pow (x, y); }
00064 inline double pow (const double& x, const int& y) {
00065 return std::pow (x, (double) y); }
00066 inline double pow (const int& x, const double& y) {
00067 return std::pow ((double) x, y); }
00068
00069 INV_TRIGO_SUGAR(,double)
00070 INV_HYPER_SUGAR(,double)
00071 ARG_HYPER_SUGAR(,double)
00072
00073
00074
00075
00076
00077 inline bool is_finite (const double& x) { return std::isfinite (x); }
00078 inline bool is_infinite (const double& x) { return std::isinf (x); }
00079 inline bool is_fuzz (const double& x) { (void) x; return false; }
00080 inline bool is_nan (const double& x) { return std::isnan (x); }
00081 inline bool is_reliable (const double& x) { (void) x; return false; }
00082
00083 inline xnat precision (const double& x) { (void) x; return 51; }
00084 inline double change_precision (const double& x, xnat prec) {
00085 ASSERT (prec == 51, "invalid precision"); return x; }
00086 inline double next_above (const double& x) { return nextafter (x, HUGE_VAL); }
00087 inline double next_below (const double& x) { return nextafter (x, -HUGE_VAL); }
00088 inline double rounding_error (const double& x) {
00089 return ldexp (nextafter (abs (x), HUGE_VAL), -50) + __DBL_MIN__; }
00090 inline double additive_error (const double& x) {
00091 return ldexp (nextafter (abs (x), HUGE_VAL), -50); }
00092
00093 STMPL inline double magnitude (const double& x) { return log2 (x); }
00094 inline xint exponent (const double& x) {
00095 return (xint) max (-10000.0, logb (x)); }
00096
00097
00098
00099
00100
00101 template<typename S> inline double
00102 incexp2 (const double& x, const S& y) { return ldexp (x, y); }
00103 inline double
00104 incexp2 (const double& x) { return ldexp (x, 1); }
00105 template<typename S> inline void
00106 incexp2_assign (double& x, const S& y) { x= ldexp (x, y); }
00107 template<typename S> inline void
00108 incexp2 (double& x, const double& y, const S& z) { x= ldexp (y, z); }
00109 template<typename S> inline double
00110 decexp2 (const double& x, const S& y) { return ldexp (x, -y); }
00111 inline double
00112 decexp2 (const double& x) { return ldexp (x, -1); }
00113 template<typename S> inline void
00114 decexp2_assign (double& x, const S& y) { x= ldexp (x, -y); }
00115 template<typename S> inline void
00116 decexp2 (double& x, const double& y, const S& z) { x= ldexp (y, -z); }
00117
00118
00119
00120
00121
00122 inline int as_int (const double& x) { return (int) x; }
00123 inline double as_double (const double& x) { return x; }
00124 inline double int_as_double (const int& x) { return (double) x; }
00125
00126 inline double square (const double& x) { return x * x; }
00127 inline double invert (const double& x) { return 1.0 / x; }
00128
00129 inline double floor (const double& x) { return std::floor (x); }
00130 inline double trunc (const double& x) { return ::trunc (x); }
00131 inline double ceil (const double& x) { return std::ceil (x); }
00132 inline double round (const double& x) { return std::floor (x + 0.5); }
00133
00134 double uniform_deviate (const double& lo, const double& hi);
00135
00136
00137
00138
00139
00140 #define mmx_sqrt mmx::sqrt
00141 #define mmx_hypot mmx::hypot
00142 #define mmx_pow mmx::pow
00143 #define mmx_exp mmx::exp
00144 #define mmx_exp2 mmx::exp2
00145 #define mmx_log mmx::log
00146 #define mmx_log2 mmx::log2
00147 #define mmx_cos mmx::cos
00148 #define mmx_sin mmx::sin
00149 #define mmx_tan mmx::tan
00150 #define mmx_cosh mmx::cosh
00151 #define mmx_sinh mmx::sinh
00152 #define mmx_tanh mmx::tanh
00153 #define mmx_acos mmx::acos
00154 #define mmx_asin mmx::asin
00155 #define mmx_atan mmx::atan
00156 #define mmx_atan2 mmx::atan2
00157 #define mmx_floor mmx::floor
00158 #define mmx_trunc mmx::trunc
00159 #define mmx_ceil mmx::ceil
00160 #define mmx_round mmx::round
00161
00162 }
00163 #endif // __MMX__DOUBLE_HPP__