@@ -79,3 +79,71 @@ TEST(BFloat16, BF16ToFloat) {
7979  ASSERT_EQ (Res,
8080            bitsToFloatConv (std::string (" 11111111011111110000000000000000"  )));
8181}
82+ 
83+ TEST (BFloat16, BF16Limits) {
84+   namespace  sycl_ext  =  sycl::ext::oneapi;
85+   using  Limit = std::numeric_limits<sycl_ext::bfloat16>;
86+   constexpr  float  Log10_2 = 0 .30103f ;
87+   auto  constexpr_ceil = [](float  Val) constexpr  -> int  {
88+     return  Val + (float (int (Val)) == Val ? 0 .f  : 1 .f );
89+   };
90+ 
91+   static_assert (Limit::is_specialized);
92+   static_assert (Limit::is_signed);
93+   static_assert (!Limit::is_integer);
94+   static_assert (!Limit::is_exact);
95+   static_assert (Limit::has_infinity);
96+   static_assert (Limit::has_quiet_NaN);
97+   static_assert (Limit::has_signaling_NaN);
98+   static_assert (Limit::has_denorm == std::float_denorm_style::denorm_present);
99+   static_assert (!Limit::has_denorm_loss);
100+   static_assert (!Limit::tinyness_before);
101+   static_assert (!Limit::traps);
102+   static_assert (Limit::max_exponent10 == 35 );
103+   static_assert (Limit::max_exponent == 127 );
104+   static_assert (Limit::min_exponent10 == -37 );
105+   static_assert (Limit::min_exponent == -126 );
106+   static_assert (Limit::radix == 2 );
107+   static_assert (Limit::digits == 8 );
108+   static_assert (Limit::max_digits10 ==
109+                 constexpr_ceil (float (Limit::digits) * Log10_2 + 1 .0f ));
110+   static_assert (Limit::is_bounded);
111+   static_assert (Limit::digits10 == int (Limit::digits * Log10_2));
112+   static_assert (!Limit::is_modulo);
113+   static_assert (Limit::is_iec559);
114+   static_assert (Limit::round_style == std::float_round_style::round_to_nearest);
115+ 
116+   EXPECT_TRUE (sycl_ext::experimental::isnan (Limit::quiet_NaN ()));
117+   EXPECT_TRUE (sycl_ext::experimental::isnan (Limit::signaling_NaN ()));
118+   //  isinf does not exist for bfloat16 currently.
119+   EXPECT_EQ (Limit::infinity (),
120+             sycl::bit_cast<sycl_ext::bfloat16>(uint16_t (0xff  << 7 )));
121+   EXPECT_EQ (Limit::round_error (), sycl_ext::bfloat16 (0 .5f ));
122+   EXPECT_GT (sycl_ext::bfloat16{1 .0f } + Limit::epsilon (),
123+             sycl_ext::bfloat16{1 .0f });
124+ 
125+   for  (uint16_t  Sign : {0 , 1 })
126+     for  (uint16_t  Exponent = 0 ; Exponent < 0xff ; ++Exponent)
127+       for  (uint16_t  Significand = 0 ; Significand < 0x7f ; ++Significand) {
128+         const  auto  Value = sycl::bit_cast<sycl_ext::bfloat16>(
129+             uint16_t ((Sign << 15 ) | (Exponent << 7 ) | Significand));
130+ 
131+         EXPECT_LE (Limit::lowest (), Value);
132+         EXPECT_GE (Limit::max (), Value);
133+ 
134+         //  min() is the lowest normal number, so if Value is negative, 0 or a
135+         //  subnormal - the latter two being represented by a 0-exponent - min()
136+         //  must be strictly greater.
137+         if  (Sign || Exponent == 0x0 )
138+           EXPECT_GT (Limit::min (), Value);
139+         else 
140+           EXPECT_LE (Limit::min (), Value);
141+ 
142+         //  denorm_min() is the lowest subnormal number, so if Value is negative
143+         //  or 0 denorm_min() must be strictly greater.
144+         if  (Sign || (Exponent == 0x0  && Significand == 0x0 ))
145+           EXPECT_GT (Limit::denorm_min (), Value);
146+         else 
147+           EXPECT_LE (Limit::denorm_min (), Value);
148+       }
149+ }
0 commit comments