From 0805756259b8e834a9e4a9a1c9c9474fc92d0498 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Sun, 14 Aug 2016 16:54:42 +0900 Subject: [PATCH] add carry_to_exp2 --- sprout/integer.hpp | 1 + sprout/integer/carry_to_exp2.hpp | 75 ++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 sprout/integer/carry_to_exp2.hpp diff --git a/sprout/integer.hpp b/sprout/integer.hpp index 0c35f32c..f2f4d2d1 100644 --- a/sprout/integer.hpp +++ b/sprout/integer.hpp @@ -10,6 +10,7 @@ #include #include +#include #include #endif // #ifndef SPROUT_INTEGER_HPP diff --git a/sprout/integer/carry_to_exp2.hpp b/sprout/integer/carry_to_exp2.hpp new file mode 100644 index 00000000..698384fb --- /dev/null +++ b/sprout/integer/carry_to_exp2.hpp @@ -0,0 +1,75 @@ +/*============================================================================= + Copyright (c) 2011-2016 Bolero MURAKAMI + https://github.com/bolero-MURAKAMI/Sprout + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef SPROUT_INTEGER_CARRY_TO_EXP2_HPP +#define SPROUT_INTEGER_CARRY_TO_EXP2_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace detail { + template + inline SPROUT_CONSTEXPR IntType + carry_to_exp2_simpl(IntType x) { + return sprout::popcount(x) <= 1 ? x + : IntType(1) << (sizeof(IntType) * CHAR_BIT - sprout::cntl0(x)) + ; + } + template + inline SPROUT_CONSTEXPR UIntType + carry_to_exp2_uimpl(int n) { + return !n ? UIntType(0) + : UIntType(1) << (sizeof(UIntType) * CHAR_BIT - n) + ; + } + } // namespace detail + // + // carry_to_exp2 + // + // note: for signed integer + // x == MIN + // --> carry_to_exp2(x) returns x . + // x < 0 + // --> carry_to_exp2(x) returns -carry_to_exp2(-x) . + // -(MIN / 2) < x + // --> carry_to_exp2(x) returns MIN . + // + // note: for unsigned integer + // MAX / 2 + 1 < x + // --> carry_to_exp2(x) returns 0 . + // + template< + typename IntType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR IntType + carry_to_exp2(IntType x) { + return x == std::numeric_limits::min() ? x + : x < IntType(0) ? -sprout::detail::carry_to_exp2_simpl(-x) + : sprout::detail::carry_to_exp2_simpl(x) + ; + } + template< + typename UIntType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR UIntType + carry_to_exp2(UIntType x) { + return sprout::popcount(x) <= 1 ? x + : sprout::detail::carry_to_exp2_uimpl(sprout::cntl0(x)) + ; + } +} // namespace sprout + +#endif // #ifndef SPROUT_INTEGER_CARRY_TO_EXP2_HPP