28 #ifndef VC_COMMON_MATH_H_
29 #define VC_COMMON_MATH_H_
31 #define Vc_COMMON_MATH_H_INTERNAL 1
33 #include "trigonometric.h"
38 namespace Vc_VERSIONED_NAMESPACE
41 template <
class T,
class Abi>
42 SimdArray<int, Vector<T, Abi>::size()> fpclassify(
const Vector<T, Abi> &x)
44 return SimdArray<int, Vector<T, Abi>::size()>(
45 [&](std::size_t i) {
return std::fpclassify(x[i]); });
47 template <
class T,
size_t N> SimdArray<int, N> fpclassify(
const SimdArray<T, N> &x)
49 return SimdArray<int, N>([&](std::size_t i) {
return std::fpclassify(x[i]); });
54 #include "logarithm.h"
55 #include "exponential.h"
59 AVX::Vector<double> x = _x;
60 typedef AVX::Vector<double> V;
62 typedef AVX::Const<double> C;
64 const M overflow = x > Vc::Detail::doubleConstant< 1, 0x0006232bdd7abcd2ull, 9>();
65 const M underflow = x < Vc::Detail::doubleConstant<-1, 0x0006232bdd7abcd2ull, 9>();
67 V px =
floor(C::log2_e() * x + 0.5);
68 __m128i tmp = _mm256_cvttpd_epi32(px.data());
69 const SimdArray<int, V::Size> n =
SSE::int_v{tmp};
70 x -= px * C::ln2_large();
71 x -= px * C::ln2_small();
74 Vc::Detail::doubleConstant<1, 0x000089cdd5e44be8ull, -13>(),
75 Vc::Detail::doubleConstant<1, 0x000f06d10cca2c7eull, -6>(),
76 Vc::Detail::doubleConstant<1, 0x0000000000000000ull, 0>()
79 Vc::Detail::doubleConstant<1, 0x00092eb6bc365fa0ull, -19>(),
80 Vc::Detail::doubleConstant<1, 0x0004ae39b508b6c0ull, -9>(),
81 Vc::Detail::doubleConstant<1, 0x000d17099887e074ull, -3>(),
82 Vc::Detail::doubleConstant<1, 0x0000000000000000ull, 1>()
85 px = x * ((P[0] * x2 + P[1]) * x2 + P[2]);
86 x = px / ((((Q[0] * x2 + Q[1]) * x2 + Q[2]) * x2 + Q[3]) - px);
91 x(overflow) = std::numeric_limits<double>::infinity();
99 SSE::Vector<double> x = _x;
100 typedef SSE::Vector<double> V;
102 typedef SSE::Const<double> C;
104 const M overflow = x > Vc::Detail::doubleConstant< 1, 0x0006232bdd7abcd2ull, 9>();
105 const M underflow = x < Vc::Detail::doubleConstant<-1, 0x0006232bdd7abcd2ull, 9>();
107 V px =
floor(C::log2_e() * x + 0.5);
108 SimdArray<int, V::Size> n;
109 _mm_storel_epi64(
reinterpret_cast<__m128i *
>(&n), _mm_cvttpd_epi32(px.data()));
110 x -= px * C::ln2_large();
111 x -= px * C::ln2_small();
114 Vc::Detail::doubleConstant<1, 0x000089cdd5e44be8ull, -13>(),
115 Vc::Detail::doubleConstant<1, 0x000f06d10cca2c7eull, -6>(),
116 Vc::Detail::doubleConstant<1, 0x0000000000000000ull, 0>()
119 Vc::Detail::doubleConstant<1, 0x00092eb6bc365fa0ull, -19>(),
120 Vc::Detail::doubleConstant<1, 0x0004ae39b508b6c0ull, -9>(),
121 Vc::Detail::doubleConstant<1, 0x000d17099887e074ull, -3>(),
122 Vc::Detail::doubleConstant<1, 0x0000000000000000ull, 1>()
125 px = x * ((P[0] * x2 + P[1]) * x2 + P[2]);
126 x = px / ((((Q[0] * x2 + Q[1]) * x2 + Q[2]) * x2 + Q[3]) - px);
131 x(overflow) = std::numeric_limits<double>::infinity();
132 x.setZero(underflow);
140 #undef Vc_COMMON_MATH_H_INTERNAL
142 #endif // VC_COMMON_MATH_H_