Brick icon

Signed Integer Operations

Brick | PRO | 10/19/17 10:31:16 AM UTC | 0 ⭐ | 284 👁️ | Never ⏰ | []
C++ |

1.2 KB

|

None

|

0 👍

/

0 👎

#include <type_traits>
#include <limits>
 
constexpr bool native_asr = (-2 >> 1) == -1;
 
template <typename T>
constexpr inline typename std::make_signed<T>::type sign_extend_shift(const T value, const std::size_t shift) noexcept
{
    return (value << shift) >> shift;
}
 
template <typename T>
constexpr inline typename std::make_signed<T>::type sign_extend_mask(const T value, const T mask) noexcept
{
    return (value ^ mask) - mask;
}
 
template <typename T>
constexpr inline typename std::make_signed<T>::type sign_extend(const T value, const std::size_t bit_count) noexcept
{
    return (native_asr)
        ? sign_extend_shift(value, std::numeric_limits<typename std::make_unsigned<T>::type>::digits - bit_count)
        : sign_extend_mask<T>(value, static_cast<typename std::make_unsigned<T>::type>(1) << (bit_count - 1));
}
 
template <typename T>
constexpr inline T arithmetic_shift_right(const T value, const std::size_t shift) noexcept
{
    return (native_asr)
        ? (value >> shift)
        : sign_extend<T>(
            static_cast<typename std::make_unsigned<T>::type>(value) >> shift,
            std::numeric_limits<typename std::make_unsigned<T>::type>::digits - shift);
}

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎