mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-01-18 17:31:19 +01:00
committed by
Antonio Sánchez
parent
c5aa40675a
commit
c30af8f3db
@@ -56,19 +56,21 @@ struct random_bits_impl {
|
||||
EIGEN_STATIC_ASSERT(std::is_unsigned<Scalar>::value, SCALAR MUST BE A BUILT - IN UNSIGNED INTEGER)
|
||||
using RandomDevice = eigen_random_device;
|
||||
using RandomReturnType = typename RandomDevice::ReturnType;
|
||||
static constexpr int kEntropy = RandomDevice::Entropy;
|
||||
static constexpr int kTotalBits = sizeof(Scalar) * CHAR_BIT;
|
||||
static constexpr int kEntropy = plain_enum_min(kTotalBits, RandomDevice::Entropy);
|
||||
// return a Scalar filled with numRandomBits beginning from the least significant bit
|
||||
static EIGEN_DEVICE_FUNC inline Scalar run(int numRandomBits) {
|
||||
eigen_assert((numRandomBits >= 0) && (numRandomBits <= kTotalBits));
|
||||
const Scalar mask = Scalar(-1) >> ((kTotalBits - numRandomBits) & (kTotalBits - 1));
|
||||
Scalar randomBits = 0;
|
||||
for (int shift = 0; shift < numRandomBits; shift += kEntropy) {
|
||||
RandomReturnType r = RandomDevice::run();
|
||||
randomBits |= static_cast<Scalar>(r) << shift;
|
||||
for (int filledBits = 0; filledBits < numRandomBits; filledBits += kEntropy) {
|
||||
Scalar r = static_cast<Scalar>(RandomDevice::run());
|
||||
int remainingBits = numRandomBits - filledBits;
|
||||
if (remainingBits < kEntropy) {
|
||||
// clear the excess bits to avoid UB and rounding bias
|
||||
r >>= kEntropy - remainingBits;
|
||||
}
|
||||
randomBits |= r << filledBits;
|
||||
}
|
||||
// clear the excess bits
|
||||
randomBits &= mask;
|
||||
return randomBits;
|
||||
}
|
||||
};
|
||||
@@ -204,7 +206,8 @@ struct random_int_impl<Scalar, false, true> {
|
||||
template <typename Scalar>
|
||||
struct random_int_impl<Scalar, true, true> {
|
||||
static constexpr int kTotalBits = sizeof(Scalar) * CHAR_BIT;
|
||||
using BitsType = typename make_unsigned<Scalar>::type;
|
||||
// avoid implicit integral promotion to `int`
|
||||
using BitsType = std::conditional_t<(sizeof(Scalar) < sizeof(int)), unsigned int, std::make_unsigned_t<Scalar> >;
|
||||
static EIGEN_DEVICE_FUNC inline Scalar run(const Scalar& x, const Scalar& y) {
|
||||
if (y <= x) return x;
|
||||
// Avoid overflow by representing `range` as an unsigned type
|
||||
|
||||
@@ -721,7 +721,7 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC float half_to_float(__half_raw h) {
|
||||
o_bits = Eigen::numext::bit_cast<uint32_t>(Eigen::numext::bit_cast<float>(o_bits) - magic);
|
||||
}
|
||||
|
||||
o_bits |= (h.x & 0x8000) << 16; // sign bit
|
||||
o_bits |= (h.x & 0x8000u) << 16; // sign bit
|
||||
return Eigen::numext::bit_cast<float>(o_bits);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -83,7 +83,9 @@ class HistogramHelper {
|
||||
|
||||
// helper class to avoid extending std:: namespace
|
||||
template <typename T>
|
||||
struct get_range_type : internal::make_unsigned<T> {};
|
||||
struct get_range_type {
|
||||
using type = std::conditional_t<(sizeof(T) < sizeof(int)), unsigned int, std::make_unsigned_t<T>>;
|
||||
};
|
||||
template <typename T>
|
||||
struct get_range_type<SafeScalar<T>> : internal::make_unsigned<T> {};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user