@@ -372,5 +372,69 @@ TEST(Float16Test, FromBytes) {
372372 ASSERT_EQ (Float16::FromBigEndian (bytes.data ()), Float16::FromBits (0x1cd0 ));
373373}
374374
375+ TEST (Float16Test, NumericLimits) {
376+ using F16 = std::numeric_limits<Float16>;
377+ using F32 = std::numeric_limits<float >;
378+
379+ // Boolean traits - should match standard float
380+ ASSERT_EQ (F16 ::is_specialized, F32 ::is_specialized);
381+ ASSERT_EQ (F16 ::is_signed, F32 ::is_signed);
382+ ASSERT_EQ (F16 ::is_integer, F32 ::is_integer);
383+ ASSERT_EQ (F16 ::is_exact, F32 ::is_exact);
384+ ASSERT_EQ (F16 ::has_infinity, F32 ::has_infinity);
385+ ASSERT_EQ (F16 ::has_quiet_NaN, F32 ::has_quiet_NaN);
386+ ASSERT_EQ (F16 ::has_signaling_NaN, F32 ::has_signaling_NaN);
387+ ASSERT_EQ (F16 ::has_denorm, F32 ::has_denorm);
388+ ASSERT_EQ (F16 ::has_denorm_loss, F32 ::has_denorm_loss);
389+ ASSERT_EQ (F16 ::is_iec559, F32 ::is_iec559);
390+ ASSERT_EQ (F16 ::is_bounded, F32 ::is_bounded);
391+ ASSERT_EQ (F16 ::is_modulo, F32 ::is_modulo);
392+ ASSERT_EQ (F16 ::radix, F32 ::radix);
393+
394+ // Check if IEEE 754 is implemented correctly.
395+ // Precision and exponent range
396+ ASSERT_EQ (F16 ::digits, 11 );
397+ ASSERT_EQ (F16 ::digits10, 3 );
398+ ASSERT_EQ (F16 ::max_digits10, 5 );
399+ ASSERT_EQ (F16 ::min_exponent, -13 );
400+ ASSERT_EQ (F16 ::max_exponent, 16 );
401+ ASSERT_EQ (F16 ::min_exponent10, -4 );
402+ ASSERT_EQ (F16 ::max_exponent10, 4 );
403+
404+ // Special values
405+ ASSERT_FLOAT_EQ (F16::max ().ToFloat (), 65504 .0f ); // Largest finite value
406+ ASSERT_EQ (F16::lowest (), -F16::max ()); // Most negative = -max
407+ ASSERT_FLOAT_EQ (F16::epsilon ().ToFloat (), 0 .0009765625f ); // 2^-10
408+ ASSERT_FLOAT_EQ (F16::round_error ().ToFloat (), 0 .5f ); // Round-to-nearest
409+ ASSERT_TRUE (F16::infinity ().is_infinity ());
410+ ASSERT_FALSE (F16::infinity ().signbit ());
411+ ASSERT_TRUE ((-F16::infinity ()).is_infinity ());
412+ ASSERT_TRUE ((-F16::infinity ()).signbit ());
413+ ASSERT_TRUE (F16::quiet_NaN ().is_nan ());
414+ ASSERT_TRUE (F16::signaling_NaN ().is_nan ());
415+
416+ // min() is smallest positive normal, denorm_min() is smallest subnormal
417+ ASSERT_TRUE (F16::min ().is_finite ());
418+ ASSERT_FALSE (F16::min ().signbit ());
419+ ASSERT_TRUE (F16::denorm_min ().is_finite ());
420+ ASSERT_FALSE (F16::denorm_min ().signbit ());
421+
422+ // Verify special values semantics
423+ ASSERT_TRUE (F16::infinity ().is_infinity ());
424+ ASSERT_TRUE ((-F16::infinity ()).is_infinity ());
425+ ASSERT_TRUE (F16::min () > Float16::FromBits (0 ));
426+ ASSERT_TRUE (F16::denorm_min () > Float16::FromBits (0 ));
427+ ASSERT_TRUE (F16::denorm_min () < F16::min ());
428+
429+ // Verify epsilon: 1 + epsilon != 1
430+ auto one = Float16 (1 .0f );
431+ auto one_plus_epsilon = Float16 (one.ToFloat () + F16::epsilon ().ToFloat ());
432+ ASSERT_NE (one, one_plus_epsilon);
433+
434+ // Verify round_error is 0.5
435+ ASSERT_FLOAT_EQ (F16::round_error ().ToFloat (), 0 .5f );
436+ ASSERT_FLOAT_EQ (F32::round_error (), 0 .5f );
437+ }
438+
375439} // namespace
376440} // namespace arrow::util
0 commit comments