1#ifndef SISCO_BIT_FLOAT_H_
2#define SISCO_BIT_FLOAT_H_
29 return "negative zero";
35 return "signalling nan";
39 return "negative infinity";
43 __builtin_unreachable();
62 :
mantissa_((
std::bit_cast<uint32_t>(f) & 0x007FFFFF) | 0x00800000),
63 exponent_(static_cast<int8_t>((
std::bit_cast<uint32_t>(f) & 0x7F800000) >> 23) - 127),
64 sign_(
std::bit_cast<uint32_t>(f) & 0x80000000) {
89 throw std::overflow_error(
"An overflow occured! Value = " + std::to_string(
ToFloat()) +
90 ", exponent = " + std::to_string(
exponent_) +
", mantissa = " +
100 constexpr static std::pair<uint32_t, bool>
UnpackMantissa(uint32_t mantissa_with_sign) {
101 const uint32_t mantissa = (mantissa_with_sign & 0x7FFFFFFFu);
102 const bool sign = (mantissa_with_sign & 0x80000000u) != 0u;
103 return {mantissa,
sign};
112 const std::pair<uint32_t, bool> unpacked =
UnpackMantissa(mantissa_with_sign);
113 return BitFloat(unpacked.first, exponent, unpacked.second);
182 while (result & 0xFF000000) {
184 result = (result >> 1);
186 while ((result & 0x00800000) == 0) {
188 result = (result << 1);
192 result = (result & 0x007FFFFF) |
193 (
static_cast<uint32_t
>(
static_cast<uint8_t
>(exponent + 127)) << 23) |
194 (
sign_ ? 0x80000000 : 0x0);
195 return std::bit_cast<float>(result);
198 explicit constexpr operator float()
const {
return ToFloat(); }
210 return exponent !=
static_cast<int8_t
>(128u) && exponent != -127;
238 friend constexpr std::optional<BitFloat>
Match(
const BitFloat& input, int8_t value_exponent) {
239 if (input.
Exponent() == value_exponent) {
241 }
else if (input.
Exponent() > value_exponent) {
242 const uint8_t shift = input.
Exponent() - value_exponent;
248 const uint8_t shift = value_exponent - input.
Exponent();
262 const uint32_t
value = std::bit_cast<uint32_t>(f);
265 }
else if (
value == 0x80000000) {
267 }
else if ((
value & 0x7F800000) == 0x7F800000) {
269 if (
value & 0x00400000)
273 }
else if ((
value & 0x7FFFFFFF) == 0b1111111100000000000000000000000) {
274 if (
value & 0x80000000)
278 }
else if ((
value & 0x7F800000) == 0) {
static constexpr BitFloat FromCompressed(uint32_t mantissa_with_sign, int8_t exponent)
Constructs a BitFloat from a 'packed mantissa' (see PackMantissa()) and the exponent.
constexpr BitFloat & operator-=(const BitFloat &rhs)
Like operator+=, but subtracts rhs.
constexpr bool Sign() const
constexpr bool MantissaOverflow() const
Returns true if bit 32 is set.
constexpr uint32_t PackMantissa() const
Combines the sign and the mantissa into one uint32_t.
constexpr BitFloat()
Constructs a zero-value BitFloat.
friend constexpr bool operator==(const BitFloat &lhs, const BitFloat &rhs)
static constexpr std::pair< uint32_t, bool > UnpackMantissa(uint32_t mantissa_with_sign)
Given a result from PackMantissa(), this function reversed the packing.
constexpr BitFloat & operator*=(unsigned factor)
Multiplies the value by an integer factor.
static constexpr BitFloatKind GetKind(float f)
Determine what kind of float the specified value is: normal, nan, inf, etc.
constexpr BitFloat(uint32_t mantissa, int8_t exponent, bool sign)
friend constexpr std::optional< BitFloat > Match(const BitFloat &input, int8_t value_exponent)
Shifts the input value such that its exponent matches the specified exponent.
constexpr BitFloat & operator+=(const BitFloat &rhs)
Adds the value rhs to this.
constexpr int8_t Exponent() const
static constexpr bool AllowsMath(int8_t exponent)
Based on the exponent, determines if this is a special value and should not be used in mathematical o...
constexpr BitFloat & operator/=(unsigned factor)
Divides the value by an integer factor.
friend constexpr BitFloat operator-(const BitFloat &input)
Negation; flips the sign of the value.
constexpr BitFloat(float f)
Constructs a BitFloat by decomposing the specified floating point value.
constexpr float ToFloat() const
Compose this value back into a single-precision floating point value.
constexpr uint32_t Mantissa() const
constexpr bool AllowsMath() const
Normal or Gaussian distribution.
For temporary backward namespace compatibility, use casa as alias for casacore.
constexpr std::string_view ToString(BitFloatKind kind)
LatticeExprNode sign(const LatticeExprNode &expr)
NewDelAllocator< T > NewDelAllocator< T >::value
Define real & complex conjugation for non-complex types and put comparisons into std namespace.