40 operator __bf16 (this
bf16 self) noexcept {
return self.content; }
43 operator float (
this bf16 self)
noexcept {
return self.content; }
54 friend constexpr
bool operator == (
bf16 x,
bf16 y) noexcept {
60 return x.content <=> y.content;
65 return x.content != y.content;
70 return x.content < y.content;
75 return x.content > y.content;
80 return x.content <= y.content;
85 return x.content >= y.content;
89 friend constexpr void swap(
94 swap(x.content,y.content);
99 return std::bit_cast<bf16>(data);
104 return std::bit_cast<uint16_t>(self.content);
109constexpr bf16 operator""_bf16(
long double v)
noexcept {
110 return bf16(
static_cast<float>(v));
118 return std::bit_cast<bf16>(
static_cast<uint16_t
>(std::bit_cast<uint32_t>(f)>>16));
133 return (x.to_bits() & 0x7FFF) > 0x7F80;
138 static constexpr bool is_specialized =
true;
151 static constexpr int digits = 7;
152 static constexpr int digits10 = 2;
153 static constexpr bool is_signed =
true;
154 static constexpr bool is_integer =
false;
155 static constexpr bool is_exact =
false;
156 static constexpr int radix = 2;
165 static constexpr int min_exponent = -125;
166 static constexpr int min_exponent10 = -37;
167 static constexpr int max_exponent = 128;
168 static constexpr int max_exponent10 = 38;
169 static constexpr bool has_infinity =
true;
170 static constexpr bool has_quiet_NaN =
true;
171 static constexpr bool has_signaling_NaN =
true;
172 static constexpr float_denorm_style has_denorm = denorm_absent;
173 static constexpr bool has_denorm_loss =
false;
190 static constexpr bool is_iec559 =
false;
191 static constexpr bool is_bounded =
false;
192 static constexpr bool is_modulo =
false;
193 static constexpr bool traps =
false;
194 static constexpr bool tinyness_before =
false;
195 static constexpr float_round_style round_style = round_to_nearest;
198 extern template class numeric_limits<ein::bf16>;
202#if defined(EIN_TESTING) || defined(EIN_TESTING_BF16)
203TEST_CASE(
"bf16",
"[bf16]") {
206 SECTION(
"bf16 default constructors and conversion") {
207 CHECK(
bf16(0.5f).content == Catch::Approx(0.5f));
208 CHECK(0.25_bf16 .content == Catch::Approx(0.25f));
209 CHECK(
static_cast<float>(1.0_bf16) == Catch::Approx(1.0f));
212 SECTION(
"bf16 comparison operators") {
213 CHECK(0.5_bf16 == 0.5_bf16);
214 CHECK(0.1_bf16 < 0.2_bf16);
215 CHECK(0.3_bf16 > 0.2_bf16);
216 CHECK(0.2_bf16 <= 0.2_bf16);
217 CHECK(0.2_bf16 >= 0.2_bf16);
220 CHECK_FALSE(0.5_bf16 < 0.5_bf16);
221 CHECK_FALSE(0.3_bf16 < 0.2_bf16);
222 CHECK_FALSE(0.1_bf16 > 0.2_bf16);
223 CHECK_FALSE(0.3_bf16 <= 0.2_bf16);
224 CHECK_FALSE(0.1_bf16 >= 0.2_bf16);
227 SECTION(
"bf16 swap function") {
228 bf16 x(1.0_bf16), y(2.0_bf16);
230 CHECK(x == 2.0_bf16);
231 CHECK(y == 1.0_bf16);
234 SECTION(
"bf16 bit operations") {
235 bf16 val = bf16::from_bits(0x3F00);
236 CHECK(val.
to_bits() == 0x3F00);
237 CHECK(bf16::from_bits(0x7F80) == std::numeric_limits<bf16>::infinity());
240 SECTION(
"bf16 isnan function") {
245 SECTION(
"bf16 numeric_limits") {
246 using nl = std::numeric_limits<bf16>;
248 CHECK(nl::is_specialized);
249 CHECK(nl::is_signed);
250 CHECK(nl::digits == 7);
251 CHECK(nl::epsilon() == bf16::from_bits(0x3C00));
252 CHECK(nl::round_error() == bf16::from_bits(0x3F00));
253 CHECK(nl::min() == bf16::from_bits(0x007F));
254 CHECK(nl::max() == bf16::from_bits(0x7F7F));
255 CHECK(nl::lowest() == bf16::from_bits(0xFF7F));
256 CHECK(nl::infinity() == bf16::from_bits(0x7F80));
259 CHECK(nl::denorm_min() == bf16::from_bits(0));
static constexpr ein::bf16 infinity() noexcept
static constexpr ein::bf16 epsilon() noexcept
static constexpr ein::bf16 quiet_NaN() noexcept
static constexpr ein::bf16 round_error() noexcept
static constexpr ein::bf16 denorm_min() noexcept
static constexpr ein::bf16 lowest() noexcept
static constexpr ein::bf16 max() noexcept
static constexpr ein::bf16 min() noexcept
static constexpr ein::bf16 signaling_NaN() noexcept
#define ein_reinitializes
[[clang::reinitializes]]
#define ein_artificial
[[artificial]].
#define ein_inline
inline [[always_inline]]
#define ein_lifetimebound
[[lifetimebound]]
#define ein_noescape
portable __attribute__((noescape))
#define ein_nodiscard
C++17 [[nodiscard]].
#define ein_const
[[const]] is not const
constexpr bf16 fast_to_bf16(float f) noexcept
constexpr bool isnan(ein::bf16 x) noexcept
constexpr bf16(bf16 &&) noexcept=default
constexpr bf16(__bf16 f) noexcept
friend constexpr bool operator<(bf16 x, bf16 y) noexcept
constexpr bf16(bf16 const &) noexcept=default
static constexpr bf16 from_bits(uint16_t data) noexcept
constexpr uint16_t to_bits(this bf16 self) noexcept
friend constexpr std::partial_ordering operator<=>(bf16 x, bf16 y) noexcept
friend constexpr bool operator<=(bf16 x, bf16 y) noexcept
friend constexpr bool operator>=(bf16 x, bf16 y) noexcept
friend constexpr bool operator!=(bf16 x, bf16 y) noexcept
friend constexpr bool operator>(bf16 x, bf16 y) noexcept
friend constexpr void swap(bf16 &x, bf16 &y) noexcept
constexpr bf16() noexcept=default
ein_reinitializes constexpr bf16 & operator=(bf16 const &) noexcept=default