ia64_rounding_control.hpp 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /* Boost interval/detail/ia64_rounding_control.hpp file
  2. *
  3. * Copyright 2006-2007 Boris Gubenko
  4. *
  5. * Distributed under the Boost Software License, Version 1.0.
  6. * (See accompanying file LICENSE_1_0.txt or
  7. * copy at http://www.boost.org/LICENSE_1_0.txt)
  8. */
  9. #ifndef BOOST_NUMERIC_INTERVAL_DETAIL_IA64_ROUNDING_CONTROL_HPP
  10. #define BOOST_NUMERIC_INTERVAL_DETAIL_IA64_ROUNDING_CONTROL_HPP
  11. #if !defined(ia64) && !defined(__ia64) && !defined(__ia64__)
  12. #error This header only works on ia64 CPUs.
  13. #endif
  14. #if defined(__hpux)
  15. # include <fenv.h>
  16. namespace boost {
  17. namespace numeric {
  18. namespace interval_lib {
  19. namespace detail {
  20. struct ia64_rounding_control
  21. {
  22. typedef unsigned int rounding_mode;
  23. static void set_rounding_mode(const rounding_mode& mode) {
  24. fesetround(mode); }
  25. static void get_rounding_mode(rounding_mode& mode) { mode = fegetround(); }
  26. static void downward() { set_rounding_mode(FE_DOWNWARD); }
  27. static void upward() { set_rounding_mode(FE_UPWARD); }
  28. static void to_nearest() { set_rounding_mode(FE_TONEAREST); }
  29. static void toward_zero() { set_rounding_mode(FE_TOWARDZERO); }
  30. };
  31. } // namespace detail
  32. extern "C" {
  33. float rintf(float);
  34. double rint(double);
  35. long double rintl(long double);
  36. }
  37. template<>
  38. struct rounding_control<float>:
  39. detail::ia64_rounding_control
  40. {
  41. static float force_rounding(const float r)
  42. { volatile float _r = r; return _r; }
  43. static float to_int(const float& x) { return rintf(x); }
  44. };
  45. template<>
  46. struct rounding_control<double>:
  47. detail::ia64_rounding_control
  48. {
  49. static const double & force_rounding(const double& r) { return r; }
  50. static double to_int(const double& r) { return rint(r); }
  51. };
  52. template<>
  53. struct rounding_control<long double>:
  54. detail::ia64_rounding_control
  55. {
  56. static const long double & force_rounding(const long double& r) { return r; }
  57. static long double to_int(const long double& r) { return rintl(r); }
  58. };
  59. } // namespace interval_lib
  60. } // namespace numeric
  61. } // namespace boost
  62. #undef BOOST_NUMERIC_INTERVAL_NO_HARDWARE
  63. #endif /* __hpux */
  64. #endif /* BOOST_NUMERIC_INTERVAL_DETAIL_IA64_ROUNDING_CONTROL_HPP */