mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Bit shifting functions
This commit is contained in:
committed by
Rasmus Munk Larsen
parent
9700fc847a
commit
8e47971789
@@ -1068,24 +1068,45 @@ void min_max(const ArrayType& m) {
|
||||
}
|
||||
}
|
||||
|
||||
template <int N>
|
||||
struct shift_left {
|
||||
template <typename Scalar>
|
||||
Scalar operator()(const Scalar& v) const {
|
||||
return (v << N);
|
||||
template <typename Scalar>
|
||||
struct shift_imm_traits {
|
||||
enum { Cost = 1, PacketAccess = internal::packet_traits<Scalar>::HasShift };
|
||||
};
|
||||
|
||||
template <int N, typename Scalar>
|
||||
struct logical_left_shift_op {
|
||||
Scalar operator()(const Scalar& v) const { return numext::logical_shift_left(v, N); }
|
||||
template <typename Packet>
|
||||
Packet packetOp(const Packet& v) const {
|
||||
return internal::plogical_shift_left<N>(v);
|
||||
}
|
||||
};
|
||||
template <int N, typename Scalar>
|
||||
struct logical_right_shift_op {
|
||||
Scalar operator()(const Scalar& v) const { return numext::logical_shift_right(v, N); }
|
||||
template <typename Packet>
|
||||
Packet packetOp(const Packet& v) const {
|
||||
return internal::plogical_shift_right<N>(v);
|
||||
}
|
||||
};
|
||||
template <int N, typename Scalar>
|
||||
struct arithmetic_right_shift_op {
|
||||
Scalar operator()(const Scalar& v) const { return numext::arithmetic_shift_right(v, N); }
|
||||
template <typename Packet>
|
||||
Packet packetOp(const Packet& v) const {
|
||||
return internal::parithmetic_shift_right<N>(v);
|
||||
}
|
||||
};
|
||||
|
||||
template <int N>
|
||||
struct arithmetic_shift_right {
|
||||
template <typename Scalar>
|
||||
Scalar operator()(const Scalar& v) const {
|
||||
return (v >> N);
|
||||
}
|
||||
};
|
||||
template <int N, typename Scalar>
|
||||
struct internal::functor_traits<logical_left_shift_op<N, Scalar>> : shift_imm_traits<Scalar> {};
|
||||
template <int N, typename Scalar>
|
||||
struct internal::functor_traits<logical_right_shift_op<N, Scalar>> : shift_imm_traits<Scalar> {};
|
||||
template <int N, typename Scalar>
|
||||
struct internal::functor_traits<arithmetic_right_shift_op<N, Scalar>> : shift_imm_traits<Scalar> {};
|
||||
|
||||
template <typename ArrayType>
|
||||
struct signed_shift_test_impl {
|
||||
struct shift_test_impl {
|
||||
typedef typename ArrayType::Scalar Scalar;
|
||||
static constexpr size_t Size = sizeof(Scalar);
|
||||
static constexpr size_t MaxShift = (CHAR_BIT * Size) - 1;
|
||||
@@ -1099,20 +1120,24 @@ struct signed_shift_test_impl {
|
||||
|
||||
ArrayType m1 = ArrayType::Random(rows, cols), m2(rows, cols), m3(rows, cols);
|
||||
|
||||
m2 = m1.unaryExpr(internal::scalar_shift_right_op<Scalar, N>());
|
||||
m3 = m1.unaryExpr(arithmetic_shift_right<N>());
|
||||
m2 = m1.unaryExpr([](const Scalar& v) { return numext::logical_shift_left(v, N); });
|
||||
m3 = m1.unaryExpr(logical_left_shift_op<N, Scalar>());
|
||||
VERIFY_IS_CWISE_EQUAL(m2, m3);
|
||||
|
||||
m2 = m1.unaryExpr(internal::scalar_shift_left_op<Scalar, N>());
|
||||
m3 = m1.unaryExpr(shift_left<N>());
|
||||
m2 = m1.unaryExpr([](const Scalar& v) { return numext::logical_shift_right(v, N); });
|
||||
m3 = m1.unaryExpr(logical_right_shift_op<N, Scalar>());
|
||||
VERIFY_IS_CWISE_EQUAL(m2, m3);
|
||||
|
||||
m2 = m1.unaryExpr([](const Scalar& v) { return numext::arithmetic_shift_right(v, N); });
|
||||
m3 = m1.unaryExpr(arithmetic_right_shift_op<N, Scalar>());
|
||||
VERIFY_IS_CWISE_EQUAL(m2, m3);
|
||||
|
||||
run<N + 1>(m);
|
||||
}
|
||||
};
|
||||
template <typename ArrayType>
|
||||
void signed_shift_test(const ArrayType& m) {
|
||||
signed_shift_test_impl<ArrayType>::run(m);
|
||||
void shift_test(const ArrayType& m) {
|
||||
shift_test_impl<ArrayType>::run(m);
|
||||
}
|
||||
|
||||
template <typename ArrayType>
|
||||
@@ -1361,10 +1386,10 @@ EIGEN_DECLARE_TEST(array_cwise) {
|
||||
ArrayXXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
||||
CALL_SUBTEST_7(array_generic(Array<Index, Dynamic, Dynamic>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE),
|
||||
internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
||||
CALL_SUBTEST_8(signed_shift_test(
|
||||
CALL_SUBTEST_8(shift_test(
|
||||
ArrayXXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
||||
CALL_SUBTEST_9(signed_shift_test(Array<Index, Dynamic, Dynamic>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE),
|
||||
internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
||||
CALL_SUBTEST_9(shift_test(Array<Index, Dynamic, Dynamic>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE),
|
||||
internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
||||
CALL_SUBTEST_10(array_generic(Array<uint32_t, Dynamic, Dynamic>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE),
|
||||
internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
||||
CALL_SUBTEST_11(array_generic(Array<uint64_t, Dynamic, Dynamic>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE),
|
||||
|
||||
Reference in New Issue
Block a user