cmath_impl.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // Boost.Units - A C++ library for zero-overhead dimensional analysis and
  2. // unit/quantity manipulation and conversion
  3. //
  4. // Copyright (C) 2003-2008 Matthias Christian Schabel
  5. // Copyright (C) 2008 Steven Watanabe
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See
  8. // accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #ifndef BOOST_UNITS_CMATH_IMPL_HPP
  11. #define BOOST_UNITS_CMATH_IMPL_HPP
  12. #include <boost/config.hpp>
  13. #include <boost/math/special_functions/fpclassify.hpp>
  14. namespace boost {
  15. namespace units {
  16. namespace detail {
  17. template<class Y>
  18. inline bool isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
  19. {
  20. if((boost::math::isnan)(v1) || (boost::math::isnan)(v2)) return false;
  21. else return v1 > v2;
  22. }
  23. template<class Y>
  24. inline bool isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
  25. {
  26. if((boost::math::isnan)(v1) || (boost::math::isnan)(v2)) return false;
  27. else return v1 >= v2;
  28. }
  29. template<class Y>
  30. inline bool isless BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
  31. {
  32. if((boost::math::isnan)(v1) || (boost::math::isnan)(v2)) return false;
  33. else return v1 < v2;
  34. }
  35. template<class Y>
  36. inline bool islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
  37. {
  38. if((boost::math::isnan)(v1) || (boost::math::isnan)(v2)) return false;
  39. else return v1 <= v2;
  40. }
  41. template<class Y>
  42. inline bool islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
  43. {
  44. if((boost::math::isnan)(v1) || (boost::math::isnan)(v2)) return false;
  45. else return v1 < v2 || v1 > v2;
  46. }
  47. template<class Y>
  48. inline bool isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
  49. {
  50. return (boost::math::isnan)(v1) || (boost::math::isnan)(v2);
  51. }
  52. template<class Y>
  53. inline Y fdim BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
  54. {
  55. if((boost::math::isnan)(v1)) return v1;
  56. else if((boost::math::isnan)(v2)) return v2;
  57. else if(v1 > v2) return(v1 - v2);
  58. else return(Y(0));
  59. }
  60. #if 0
  61. template<class T>
  62. struct fma_issue_warning {
  63. enum { value = false };
  64. };
  65. template<class Y>
  66. inline Y fma(const Y& v1,const Y& v2,const Y& v3)
  67. {
  68. //this implementation does *not* meet the
  69. //requirement of infinite intermediate precision
  70. BOOST_STATIC_WARNING((fma_issue_warning<Y>::value));
  71. return v1 * v2 + v3;
  72. }
  73. #endif
  74. template<class Y>
  75. inline Y fmax BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
  76. {
  77. if((boost::math::isnan)(v1)) return(v2);
  78. else if((boost::math::isnan)(v2)) return(v1);
  79. else if(v1 > v2) return(v1);
  80. else return(v2);
  81. }
  82. template<class Y>
  83. inline Y fmin BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
  84. {
  85. if((boost::math::isnan)(v1)) return(v2);
  86. else if((boost::math::isnan)(v2)) return(v1);
  87. else if(v1 < v2) return(v1);
  88. else return(v2);
  89. }
  90. //template<class Y>
  91. //inline long long llrint(const Y& val)
  92. //{
  93. // return static_cast<long long>(rint(val));
  94. //}
  95. //
  96. //template<class Y>
  97. //inline long long llround(const Y& val)
  98. //{
  99. // return static_cast<long long>(round(val));
  100. //}
  101. #if 0
  102. template<class Y>
  103. inline Y nearbyint(const Y& val)
  104. {
  105. //this is not really correct.
  106. //the result should be according to the
  107. //current rounding mode.
  108. using boost::math::round;
  109. return round(val);
  110. }
  111. template<class Y>
  112. inline Y rint(const Y& val)
  113. {
  114. //I don't feel like trying to figure out
  115. //how to raise a floating pointer exception
  116. return nearbyint(val);
  117. }
  118. #endif
  119. template<class Y>
  120. inline Y trunc BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& val)
  121. {
  122. if(val > 0) return std::floor(val);
  123. else if(val < 0) return std::ceil(val);
  124. else return val;
  125. }
  126. }
  127. }
  128. }
  129. #endif // BOOST_UNITS_CMATH_IMPL_HPP