Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/math/special_functions/next.hpp @ 101:c530137014c0
Update Boost headers (1.58.0)
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:12:49 +0100 |
parents | 2665513ce2d3 |
children |
comparison
equal
deleted
inserted
replaced
100:793467b5e61c | 101:c530137014c0 |
---|---|
8 | 8 |
9 #ifdef _MSC_VER | 9 #ifdef _MSC_VER |
10 #pragma once | 10 #pragma once |
11 #endif | 11 #endif |
12 | 12 |
13 #include <boost/math/special_functions/math_fwd.hpp> | |
13 #include <boost/math/policies/error_handling.hpp> | 14 #include <boost/math/policies/error_handling.hpp> |
14 #include <boost/math/special_functions/fpclassify.hpp> | 15 #include <boost/math/special_functions/fpclassify.hpp> |
15 #include <boost/math/special_functions/sign.hpp> | 16 #include <boost/math/special_functions/sign.hpp> |
16 #include <boost/math/special_functions/trunc.hpp> | 17 #include <boost/math/special_functions/trunc.hpp> |
17 | 18 |
18 #ifdef BOOST_MSVC | |
19 #include <float.h> | 19 #include <float.h> |
20 | |
21 #if !defined(_CRAYC) && !defined(__CUDACC__) && (!defined(__GNUC__) || (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ > 3))) | |
22 #if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(__SSE2__) | |
23 #include "xmmintrin.h" | |
24 #define BOOST_MATH_CHECK_SSE2 | |
25 #endif | |
20 #endif | 26 #endif |
21 | 27 |
22 namespace boost{ namespace math{ | 28 namespace boost{ namespace math{ |
23 | 29 |
24 namespace detail{ | 30 namespace detail{ |
30 // numeric_limits lies about denorms being present - particularly | 36 // numeric_limits lies about denorms being present - particularly |
31 // when this can be turned on or off at runtime, as is the case | 37 // when this can be turned on or off at runtime, as is the case |
32 // when using the SSE2 registers in DAZ or FTZ mode. | 38 // when using the SSE2 registers in DAZ or FTZ mode. |
33 // | 39 // |
34 static const T m = std::numeric_limits<T>::denorm_min(); | 40 static const T m = std::numeric_limits<T>::denorm_min(); |
35 return ((tools::min_value<T>() - m) == tools::min_value<T>()) ? tools::min_value<T>() : m; | 41 #ifdef BOOST_MATH_CHECK_SSE2 |
42 return (_mm_getcsr() & (_MM_FLUSH_ZERO_ON | 0x40)) ? tools::min_value<T>() : m;; | |
43 #else | |
44 return ((tools::min_value<T>() / 2) == 0) ? tools::min_value<T>() : m; | |
45 #endif | |
36 } | 46 } |
37 | 47 |
38 template <class T> | 48 template <class T> |
39 inline T get_smallest_value(mpl::false_ const&) | 49 inline T get_smallest_value(mpl::false_ const&) |
40 { | 50 { |
101 int expon; | 111 int expon; |
102 static const char* function = "float_next<%1%>(%1%)"; | 112 static const char* function = "float_next<%1%>(%1%)"; |
103 | 113 |
104 int fpclass = (boost::math::fpclassify)(val); | 114 int fpclass = (boost::math::fpclassify)(val); |
105 | 115 |
106 if((fpclass == FP_NAN) || (fpclass == FP_INFINITE)) | 116 if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE)) |
107 { | 117 { |
108 if(val < 0) | 118 if(val < 0) |
109 return -tools::max_value<T>(); | 119 return -tools::max_value<T>(); |
110 return policies::raise_domain_error<T>( | 120 return policies::raise_domain_error<T>( |
111 function, | 121 function, |
116 return policies::raise_overflow_error<T>(function, 0, pol); | 126 return policies::raise_overflow_error<T>(function, 0, pol); |
117 | 127 |
118 if(val == 0) | 128 if(val == 0) |
119 return detail::get_smallest_value<T>(); | 129 return detail::get_smallest_value<T>(); |
120 | 130 |
121 if((fpclass != FP_SUBNORMAL) && (fpclass != FP_ZERO) && (fabs(val) < detail::get_min_shift_value<T>()) && (val != -tools::min_value<T>())) | 131 if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value<T>()) && (val != -tools::min_value<T>())) |
122 { | 132 { |
123 // | 133 // |
124 // Special case: if the value of the least significant bit is a denorm, and the result | 134 // Special case: if the value of the least significant bit is a denorm, and the result |
125 // would not be a denorm, then shift the input, increment, and shift back. | 135 // would not be a denorm, then shift the input, increment, and shift back. |
126 // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. | 136 // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. |
183 int expon; | 193 int expon; |
184 static const char* function = "float_prior<%1%>(%1%)"; | 194 static const char* function = "float_prior<%1%>(%1%)"; |
185 | 195 |
186 int fpclass = (boost::math::fpclassify)(val); | 196 int fpclass = (boost::math::fpclassify)(val); |
187 | 197 |
188 if((fpclass == FP_NAN) || (fpclass == FP_INFINITE)) | 198 if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE)) |
189 { | 199 { |
190 if(val > 0) | 200 if(val > 0) |
191 return tools::max_value<T>(); | 201 return tools::max_value<T>(); |
192 return policies::raise_domain_error<T>( | 202 return policies::raise_domain_error<T>( |
193 function, | 203 function, |
198 return -policies::raise_overflow_error<T>(function, 0, pol); | 208 return -policies::raise_overflow_error<T>(function, 0, pol); |
199 | 209 |
200 if(val == 0) | 210 if(val == 0) |
201 return -detail::get_smallest_value<T>(); | 211 return -detail::get_smallest_value<T>(); |
202 | 212 |
203 if((fpclass != FP_SUBNORMAL) && (fpclass != FP_ZERO) && (fabs(val) < detail::get_min_shift_value<T>()) && (val != tools::min_value<T>())) | 213 if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value<T>()) && (val != tools::min_value<T>())) |
204 { | 214 { |
205 // | 215 // |
206 // Special case: if the value of the least significant bit is a denorm, and the result | 216 // Special case: if the value of the least significant bit is a denorm, and the result |
207 // would not be a denorm, then shift the input, increment, and shift back. | 217 // would not be a denorm, then shift the input, increment, and shift back. |
208 // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. | 218 // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. |
316 // | 326 // |
317 // Note that if a is a denorm then the usual formula fails | 327 // Note that if a is a denorm then the usual formula fails |
318 // because we actually have fewer than tools::digits<T>() | 328 // because we actually have fewer than tools::digits<T>() |
319 // significant bits in the representation: | 329 // significant bits in the representation: |
320 // | 330 // |
321 frexp(((boost::math::fpclassify)(a) == FP_SUBNORMAL) ? tools::min_value<T>() : a, &expon); | 331 frexp(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) ? tools::min_value<T>() : a, &expon); |
322 T upper = ldexp(T(1), expon); | 332 T upper = ldexp(T(1), expon); |
323 T result = 0; | 333 T result = 0; |
324 expon = tools::digits<T>() - expon; | 334 expon = tools::digits<T>() - expon; |
325 // | 335 // |
326 // If b is greater than upper, then we *must* split the calculation | 336 // If b is greater than upper, then we *must* split the calculation |
333 // | 343 // |
334 // Use compensated double-double addition to avoid rounding | 344 // Use compensated double-double addition to avoid rounding |
335 // errors in the subtraction: | 345 // errors in the subtraction: |
336 // | 346 // |
337 T mb, x, y, z; | 347 T mb, x, y, z; |
338 if(((boost::math::fpclassify)(a) == FP_SUBNORMAL) || (b - a < tools::min_value<T>())) | 348 if(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) || (b - a < tools::min_value<T>())) |
339 { | 349 { |
340 // | 350 // |
341 // Special case - either one end of the range is a denormal, or else the difference is. | 351 // Special case - either one end of the range is a denormal, or else the difference is. |
342 // The regular code will fail if we're using the SSE2 registers on Intel and either | 352 // The regular code will fail if we're using the SSE2 registers on Intel and either |
343 // the FTZ or DAZ flags are set. | 353 // the FTZ or DAZ flags are set. |
397 // | 407 // |
398 static const char* function = "float_advance<%1%>(%1%, int)"; | 408 static const char* function = "float_advance<%1%>(%1%, int)"; |
399 | 409 |
400 int fpclass = (boost::math::fpclassify)(val); | 410 int fpclass = (boost::math::fpclassify)(val); |
401 | 411 |
402 if((fpclass == FP_NAN) || (fpclass == FP_INFINITE)) | 412 if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE)) |
403 return policies::raise_domain_error<T>( | 413 return policies::raise_domain_error<T>( |
404 function, | 414 function, |
405 "Argument val must be finite, but got %1%", val, pol); | 415 "Argument val must be finite, but got %1%", val, pol); |
406 | 416 |
407 if(val < 0) | 417 if(val < 0) |
454 expon++; | 464 expon++; |
455 } | 465 } |
456 limit_distance = float_distance(val, limit); | 466 limit_distance = float_distance(val, limit); |
457 if(distance && (limit_distance == 0)) | 467 if(distance && (limit_distance == 0)) |
458 { | 468 { |
459 policies::raise_evaluation_error<T>(function, "Internal logic failed while trying to increment floating point value %1%: most likely your FPU is in non-IEEE conforming mode.", val, pol); | 469 return policies::raise_evaluation_error<T>(function, "Internal logic failed while trying to increment floating point value %1%: most likely your FPU is in non-IEEE conforming mode.", val, pol); |
460 } | 470 } |
461 } | 471 } |
462 if((0.5f == frexp(val, &expon)) && (distance < 0)) | 472 if((0.5f == frexp(val, &expon)) && (distance < 0)) |
463 --expon; | 473 --expon; |
464 T diff = 0; | 474 T diff = 0; |