| 168 | } |
| 169 | |
| 170 | void test_numtraits() |
| 171 | { |
| 172 | std::cout << "epsilon = " << NumTraits<bfloat16>::epsilon() << " (0x" << std::hex << numext::bit_cast<numext::uint16_t>(NumTraits<bfloat16>::epsilon()) << ")" << std::endl; |
| 173 | std::cout << "highest = " << NumTraits<bfloat16>::highest() << " (0x" << std::hex << numext::bit_cast<numext::uint16_t>(NumTraits<bfloat16>::highest()) << ")" << std::endl; |
| 174 | std::cout << "lowest = " << NumTraits<bfloat16>::lowest() << " (0x" << std::hex << numext::bit_cast<numext::uint16_t>(NumTraits<bfloat16>::lowest()) << ")" << std::endl; |
| 175 | std::cout << "min = " << (std::numeric_limits<bfloat16>::min)() << " (0x" << std::hex << numext::bit_cast<numext::uint16_t>((std::numeric_limits<bfloat16>::min)()) << ")" << std::endl; |
| 176 | std::cout << "denorm min = " << (std::numeric_limits<bfloat16>::denorm_min)() << " (0x" << std::hex << numext::bit_cast<numext::uint16_t>((std::numeric_limits<bfloat16>::denorm_min)()) << ")" << std::endl; |
| 177 | std::cout << "infinity = " << NumTraits<bfloat16>::infinity() << " (0x" << std::hex << numext::bit_cast<numext::uint16_t>(NumTraits<bfloat16>::infinity()) << ")" << std::endl; |
| 178 | std::cout << "quiet nan = " << NumTraits<bfloat16>::quiet_NaN() << " (0x" << std::hex << numext::bit_cast<numext::uint16_t>(NumTraits<bfloat16>::quiet_NaN()) << ")" << std::endl; |
| 179 | std::cout << "signaling nan = " << std::numeric_limits<bfloat16>::signaling_NaN() << " (0x" << std::hex << numext::bit_cast<numext::uint16_t>(std::numeric_limits<bfloat16>::signaling_NaN()) << ")" << std::endl; |
| 180 | |
| 181 | VERIFY(NumTraits<bfloat16>::IsSigned); |
| 182 | |
| 183 | VERIFY_IS_EQUAL( |
| 184 | numext::bit_cast<numext::uint16_t>(std::numeric_limits<bfloat16>::infinity()), |
| 185 | numext::bit_cast<numext::uint16_t>(bfloat16(std::numeric_limits<float>::infinity())) ); |
| 186 | // There is no guarantee that casting a 32-bit NaN to bfloat16 has a precise |
| 187 | // bit pattern. We test that it is in fact a NaN, then test the signaling |
| 188 | // bit (msb of significand is 1 for quiet, 0 for signaling). |
| 189 | const numext::uint16_t BFLOAT16_QUIET_BIT = 0x0040; |
| 190 | VERIFY( |
| 191 | (numext::isnan)(std::numeric_limits<bfloat16>::quiet_NaN()) |
| 192 | && (numext::isnan)(bfloat16(std::numeric_limits<float>::quiet_NaN())) |
| 193 | && ((numext::bit_cast<numext::uint16_t>(std::numeric_limits<bfloat16>::quiet_NaN()) & BFLOAT16_QUIET_BIT) > 0) |
| 194 | && ((numext::bit_cast<numext::uint16_t>(bfloat16(std::numeric_limits<float>::quiet_NaN())) & BFLOAT16_QUIET_BIT) > 0) ); |
| 195 | // After a cast to bfloat16, a signaling NaN may become non-signaling. Thus, |
| 196 | // we check that both are NaN, and that only the `numeric_limits` version is |
| 197 | // signaling. |
| 198 | VERIFY( |
| 199 | (numext::isnan)(std::numeric_limits<bfloat16>::signaling_NaN()) |
| 200 | && (numext::isnan)(bfloat16(std::numeric_limits<float>::signaling_NaN())) |
| 201 | && ((numext::bit_cast<numext::uint16_t>(std::numeric_limits<bfloat16>::signaling_NaN()) & BFLOAT16_QUIET_BIT) == 0) ); |
| 202 | |
| 203 | VERIFY( (std::numeric_limits<bfloat16>::min)() > bfloat16(0.f) ); |
| 204 | VERIFY( (std::numeric_limits<bfloat16>::denorm_min)() > bfloat16(0.f) ); |
| 205 | VERIFY_IS_EQUAL( (std::numeric_limits<bfloat16>::denorm_min)()/bfloat16(2), bfloat16(0.f) ); |
| 206 | } |
| 207 | |
| 208 | void test_arithmetic() |
| 209 | { |
no test coverage detected