1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- #ifndef BOOST_MATH_SPECIAL_FIBO_HPP
- #define BOOST_MATH_SPECIAL_FIBO_HPP
- #include <boost/math/constants/constants.hpp>
- #include <boost/math/policies/error_handling.hpp>
- #include <cmath>
- #include <limits>
- #ifdef _MSC_VER
- #pragma once
- #endif
- namespace boost {
- namespace math {
- namespace detail {
- constexpr double fib_bits_phi = 0.69424191363061730173879026;
- constexpr double fib_bits_deno = 1.1609640474436811739351597;
- }
- template <typename T>
- inline BOOST_MATH_CXX14_CONSTEXPR T unchecked_fibonacci(unsigned long long n) noexcept(std::is_fundamental<T>::value) {
-
-
- if (n <= 2) return n == 0 ? 0 : 1;
-
- unsigned long long mask = 1;
- for (int ct = 1; ct != std::numeric_limits<unsigned long long>::digits && (mask << 1) <= n; ++ct, mask <<= 1)
- ;
- T a{1}, b{1};
- for (mask >>= 1; mask; mask >>= 1) {
- T t1 = a * a;
- a = 2 * a * b - t1, b = b * b + t1;
- if (mask & n)
- t1 = b, b = b + a, a = t1;
- }
- return a;
- }
- template <typename T, class Policy>
- T inline BOOST_MATH_CXX14_CONSTEXPR fibonacci(unsigned long long n, const Policy &pol) {
-
- if (n > 20 && n * detail::fib_bits_phi - detail::fib_bits_deno > std::numeric_limits<T>::digits)
- return policies::raise_overflow_error<T>("boost::math::fibonacci<%1%>(unsigned long long)", "Possible overflow detected.", pol);
- return unchecked_fibonacci<T>(n);
- }
- template <typename T>
- T inline BOOST_MATH_CXX14_CONSTEXPR fibonacci(unsigned long long n) {
- return fibonacci<T>(n, policies::policy<>());
- }
- template <typename T>
- class fibonacci_generator {
- public:
-
- T operator()() noexcept(std::is_fundamental<T>::value) {
- T ret = a;
- a = b, b = b + ret;
- return ret;
- }
-
-
- void set(unsigned long long nth) noexcept(std::is_fundamental<T>::value) {
- n = nth;
- a = unchecked_fibonacci<T>(n);
- b = unchecked_fibonacci<T>(n + 1);
- }
- private:
- unsigned long long n = 0;
- T a = 0, b = 1;
- };
- }
- }
- #endif
|