FloatingPoint.tests.cpp 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // Copyright Catch2 Authors
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // https://www.boost.org/LICENSE_1_0.txt)
  5. // SPDX-License-Identifier: BSL-1.0
  6. #include <catch2/catch_test_macros.hpp>
  7. #include <catch2/catch_template_test_macros.hpp>
  8. #include <catch2/internal/catch_floating_point_helpers.hpp>
  9. TEST_CASE("convertToBits", "[floating-point][conversion]") {
  10. using Catch::Detail::convertToBits;
  11. CHECK( convertToBits( 0.f ) == 0 );
  12. CHECK( convertToBits( -0.f ) == ( 1ULL << 31 ) );
  13. CHECK( convertToBits( 0. ) == 0 );
  14. CHECK( convertToBits( -0. ) == ( 1ULL << 63 ) );
  15. CHECK( convertToBits( std::numeric_limits<float>::denorm_min() ) == 1 );
  16. CHECK( convertToBits( std::numeric_limits<double>::denorm_min() ) == 1 );
  17. }
  18. TEMPLATE_TEST_CASE("type-shared ulpDistance tests", "[floating-point][ulp][approvals]", float, double) {
  19. using FP = TestType;
  20. using Catch::ulpDistance;
  21. // Distance between zeros is zero
  22. CHECK( ulpDistance( FP{}, FP{} ) == 0 );
  23. CHECK( ulpDistance( FP{}, -FP{} ) == 0 );
  24. CHECK( ulpDistance( -FP{}, -FP{} ) == 0 );
  25. // Distance between same-sign infinities is zero
  26. static constexpr FP infinity = std::numeric_limits<FP>::infinity();
  27. CHECK( ulpDistance( infinity, infinity ) == 0 );
  28. CHECK( ulpDistance( -infinity, -infinity ) == 0 );
  29. // Distance between max-finite-val and same sign infinity is 1
  30. static constexpr FP max_finite = std::numeric_limits<FP>::max();
  31. CHECK( ulpDistance( max_finite, infinity ) == 1 );
  32. CHECK( ulpDistance( -max_finite, -infinity ) == 1 );
  33. // Distance between X and 0 is half of distance between X and -X
  34. CHECK( ulpDistance( -infinity, infinity ) ==
  35. 2 * ulpDistance( infinity, FP{} ) );
  36. CHECK( 2 * ulpDistance( FP{ -2. }, FP{} ) ==
  37. ulpDistance( FP{ -2. }, FP{ 2. } ) );
  38. CHECK( 2 * ulpDistance( FP{ 2. }, FP{} ) ==
  39. ulpDistance( FP{ -2. }, FP{ 2. } ) );
  40. // Denorms are supported
  41. CHECK( ulpDistance( std::numeric_limits<FP>::denorm_min(), FP{} ) == 1 );
  42. CHECK( ulpDistance( std::numeric_limits<FP>::denorm_min(), -FP{} ) == 1 );
  43. CHECK( ulpDistance( -std::numeric_limits<FP>::denorm_min(), FP{} ) == 1 );
  44. CHECK( ulpDistance( -std::numeric_limits<FP>::denorm_min(), -FP{} ) == 1 );
  45. CHECK( ulpDistance( std::numeric_limits<FP>::denorm_min(),
  46. -std::numeric_limits<FP>::denorm_min() ) == 2 );
  47. // Machine epsilon
  48. CHECK( ulpDistance( FP{ 1. },
  49. FP{ 1. } + std::numeric_limits<FP>::epsilon() ) == 1 );
  50. CHECK( ulpDistance( -FP{ 1. },
  51. -FP{ 1. } - std::numeric_limits<FP>::epsilon() ) == 1 );
  52. }
  53. TEST_CASE("UlpDistance", "[floating-point][ulp][approvals]") {
  54. using Catch::ulpDistance;
  55. CHECK( ulpDistance( 1., 2. ) == 0x10'00'00'00'00'00'00 );
  56. CHECK( ulpDistance( -2., 2. ) == 0x80'00'00'00'00'00'00'00 );
  57. CHECK( ulpDistance( 1.f, 2.f ) == 0x80'00'00 );
  58. CHECK( ulpDistance( -2.f, 2.f ) == 0x80'00'00'00 );
  59. }