File indexing completed on 2025-09-17 08:53:28
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef CATCH_RANDOM_FLOATING_POINT_HELPERS_HPP_INCLUDED
0010 #define CATCH_RANDOM_FLOATING_POINT_HELPERS_HPP_INCLUDED
0011
0012 #include <catch2/internal/catch_polyfills.hpp>
0013
0014 #include <cassert>
0015 #include <cmath>
0016 #include <cstdint>
0017 #include <limits>
0018 #include <type_traits>
0019
0020 namespace Catch {
0021
0022 namespace Detail {
0023
0024
0025
0026
0027
0028 template <typename FloatType>
0029 FloatType gamma(FloatType a, FloatType b) {
0030 static_assert( std::is_floating_point<FloatType>::value,
0031 "gamma returns the largest ULP magnitude within "
0032 "floating point range [a, b]. This only makes sense "
0033 "for floating point types" );
0034 assert( a <= b );
0035
0036 const auto gamma_up = Catch::nextafter( a, std::numeric_limits<FloatType>::infinity() ) - a;
0037 const auto gamma_down = b - Catch::nextafter( b, -std::numeric_limits<FloatType>::infinity() );
0038
0039 return gamma_up < gamma_down ? gamma_down : gamma_up;
0040 }
0041
0042 template <typename FloatingPoint>
0043 struct DistanceTypePicker;
0044 template <>
0045 struct DistanceTypePicker<float> {
0046 using type = std::uint32_t;
0047 };
0048 template <>
0049 struct DistanceTypePicker<double> {
0050 using type = std::uint64_t;
0051 };
0052
0053 template <typename T>
0054 using DistanceType = typename DistanceTypePicker<T>::type;
0055
0056 #if defined( __GNUC__ ) || defined( __clang__ )
0057 # pragma GCC diagnostic push
0058 # pragma GCC diagnostic ignored "-Wfloat-equal"
0059 #endif
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 template <typename FloatType>
0070 DistanceType<FloatType>
0071 count_equidistant_floats( FloatType a, FloatType b, FloatType distance ) {
0072 assert( a <= b );
0073
0074
0075 const auto ag = a / distance;
0076 const auto bg = b / distance;
0077
0078 const auto s = bg - ag;
0079 const auto err = ( std::fabs( a ) <= std::fabs( b ) )
0080 ? -ag - ( s - bg )
0081 : bg - ( s + ag );
0082 const auto ceil_s = static_cast<DistanceType<FloatType>>( std::ceil( s ) );
0083
0084 return ( ceil_s != s ) ? ceil_s : ceil_s + ( err > 0 );
0085 }
0086 #if defined( __GNUC__ ) || defined( __clang__ )
0087 # pragma GCC diagnostic pop
0088 #endif
0089
0090 }
0091
0092 }
0093
0094 #endif