54#ifdef HAVE_WIMPLICIT_FLOAT_CONVERSION
55 _Pragma(
"GCC diagnostic push" ) \
56 _Pragma(
"GCC diagnostic ignored \"-Wimplicit-int-float-conversion\"" )
65template <
typename in_type =
long long int,
typename ret_type =
int>
68 if constexpr( std::is_same_v<in_type, long long int> && std::is_same_v<ret_type, int> )
70 if( v > std::numeric_limits<int>::max() )
74 return std::numeric_limits<int>::max();
76 else if( v < std::numeric_limits<int>::lowest() )
80 return std::numeric_limits<int>::lowest();
98template <
typename fp_type,
typename ret_type =
int>
99constexpr ret_type
KiROUND( fp_type v,
bool aQuiet =
false )
101 using limits = std::numeric_limits<ret_type>;
103 static_assert( limits::digits <= std::numeric_limits<long long>::digits );
105 auto overflow = [&]( ret_type aResult )
114 if constexpr( std::is_integral_v<fp_type> )
116 if( std::cmp_greater( v, limits::max() ) )
117 return overflow( limits::max() );
119 if( std::cmp_less( v, limits::lowest() ) )
120 return overflow( limits::lowest() );
122 return static_cast<ret_type
>( v );
128 if constexpr( std::is_floating_point_v<fp_type> )
131 return overflow( 0 );
133 if( v >= fp_type( limits::max() ) + 0.5 )
134 return overflow( limits::max() );
137 if( v - fp_type( limits::lowest() ) <= -0.5 )
138 return overflow( limits::lowest() );
141 long long rounded = std::llround( v );
142 long long clamped = std::clamp<long long>( rounded,
static_cast<long long>( limits::lowest() ),
143 static_cast<long long>( limits::max() ) );
145 if( clamped != rounded )
146 return overflow(
static_cast<ret_type
>( clamped ) );
148 return static_cast<ret_type
>( clamped );
152#ifdef HAVE_WIMPLICIT_FLOAT_CONVERSION
153 _Pragma(
"GCC diagnostic pop" )
163 return aNumerator * aValue / aDenominator;
169 return (
T( 0 ) < val) - ( val <
T( 0 ) );
174int rescale(
int aNumerator,
int aValue,
int aDenominator );
177int64_t
rescale( int64_t aNumerator, int64_t aValue, int64_t aDenominator );
186 const T mid = ( aLo + aHi + 1 ) / 2;
209 static_assert( std::is_integral<T>::value,
"isqrt requires an integer type" );
211 constexpr T sqrt_max =
ct_sqrt( std::numeric_limits<T>::max() );
213 if constexpr( std::is_signed<T>::value )
219 T r = (
T) std::sqrt( (
double) aX );
222 while( r < sqrt_max && r * r < aX )
225 while( r > sqrt_max || r * r > aX )
237 return aX < 0 ? 0 - uint64_t( aX ) : uint64_t( aX );
251 constexpr uint64_t narrowMax =
ct_sqrt<uint64_t>( std::numeric_limits<int64_t>::max() );
256 if( ax > narrowMax || ay > narrowMax )
259 const uint64_t n = ax * ax + ay * ay;
260 const uint64_t f =
isqrt( n );
263 return f + ( n - f * f > f );
276typename std::enable_if<std::is_floating_point<T>::value,
bool>::type
277equals(
T aFirst,
T aSecond,
T aEpsilon = std::numeric_limits<T>::epsilon() )
279 const T diff =
std::abs( aFirst - aSecond );
281 if( diff < aEpsilon )
288 T largest = aFirst > aSecond ? aFirst : aSecond;
290 if( diff <= largest * aEpsilon )
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
uint64_t RoundedHypot(int64_t aX, int64_t aY)
Nearest integer to sqrt( aX^2 + aY^2 ), computed exactly.
std::enable_if< std::is_floating_point< T >::value, bool >::type equals(T aFirst, T aSecond, T aEpsilon=std::numeric_limits< T >::epsilon())
Template to compare two floating point values for equality within a required epsilon.
constexpr int sign(T val)
void kimathLogOverflow(double v, const char *aTypeName)
Workaround to avoid the empty-string conversion issue in wxWidgets.
constexpr uint64_t UnsignedAbs(int64_t aX)
Magnitude of a signed integer, well defined for INT64_MIN.
constexpr T ct_sqrt(T aX)
Floor of the square root of an integer, evaluated at compile time.
constexpr ret_type KiROUND(fp_type v, bool aQuiet=false)
Round a numeric value to an integer using "round halfway cases away from zero" and clamp the result t...
T rescale(T aNumerator, T aValue, T aDenominator)
Scale a number (value) by rational (numerator/denominator).
uint64_t RoundedHypotWide(uint64_t aX, uint64_t aY)
Nearest integer to sqrt( aX^2 + aY^2 ) for magnitudes of at most 2^63, using 128-bit arithmetic.
void kimathLogDebug(const char *aFormatString,...)
Helper to avoid directly including wx/log.h for the templated functions in kimath.
constexpr T ct_sqrt_helper(T aX, T aLo, T aHi)
constexpr ret_type KiCheckedCast(in_type v)
Perform a cast between numerical types.
T isqrt(T aX)
Exact floor of the square root of an integer.