1 // (C) Copyright John Maddock 2005.
2 // Use, modification and distribution are subject to the
3 // Boost Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 #ifndef BOOST_MATH_SERIES_INCLUDED
7 #define BOOST_MATH_SERIES_INCLUDED
11 #ifdef BOOST_NO_STDC_NAMESPACE
12 namespace std{ using ::pow; using ::fabs; }
16 namespace boost{ namespace math{ namespace detail{
19 // Algorithm kahan_sum_series invokes Functor func until the N'th
20 // term is too small to have any effect on the total, the terms
21 // are added using the Kahan summation method.
23 // CAUTION: Optimizing compilers combined with extended-precision
24 // machine registers conspire to render this algorithm partly broken:
25 // double rounding of intermediate terms (first to a long double machine
26 // register, and then to a double result) cause the rounding error computed
27 // by the algorithm to be off by up to 1ulp. However this occurs rarely, and
28 // in any case the result is still much better than a naive summation.
30 template <class Functor>
31 typename Functor::result_type kahan_sum_series(Functor& func, int bits)
33 typedef typename Functor::result_type result_type;
34 result_type factor = std::pow(result_type(2), bits);
35 result_type result = func();
36 result_type next_term, y, t;
37 result_type carry = 0;
40 y = next_term - carry;
46 while(std::fabs(result) < std::fabs(factor * next_term));
52 #endif // BOOST_MATH_SERIES_INCLUDED