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 );
127 if constexpr( std::is_floating_point_v<fp_type> )
130 return overflow( 0 );
132 if( v >= fp_type( limits::max() ) + 0.5 )
133 return overflow( limits::max() );
136 if( v - fp_type( limits::lowest() ) <= -0.5 )
137 return overflow( limits::lowest() );
140 long long rounded = std::llround( v );
141 long long clamped = std::clamp<long long>( rounded,
142 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 );
151#ifdef HAVE_WIMPLICIT_FLOAT_CONVERSION
152 _Pragma(
"GCC diagnostic pop" )
162 return aNumerator * aValue / aDenominator;
168 return (
T( 0 ) < val) - ( val <
T( 0 ) );
173int rescale(
int aNumerator,
int aValue,
int aDenominator );
176int64_t
rescale( int64_t aNumerator, int64_t aValue, int64_t aDenominator );
185 const T mid = ( aLo + aHi + 1 ) / 2;
208 static_assert( std::is_integral<T>::value,
"isqrt requires an integer type" );
210 constexpr T sqrt_max =
ct_sqrt( std::numeric_limits<T>::max() );
212 if constexpr( std::is_signed<T>::value )
218 T r = (
T) std::sqrt( (
double) aX );
221 while( r < sqrt_max && r * r < aX )
224 while( r > sqrt_max || r * r > aX )
236 return aX < 0 ? 0 - uint64_t( aX ) : uint64_t( aX );
250 constexpr uint64_t narrowMax =
ct_sqrt<uint64_t>( std::numeric_limits<int64_t>::max() );
255 if( ax > narrowMax || ay > narrowMax )
258 const uint64_t n = ax * ax + ay * ay;
259 const uint64_t f =
isqrt( n );
262 return f + ( n - f * f > f );
275typename std::enable_if<std::is_floating_point<T>::value,
bool>::type
276equals(
T aFirst,
T aSecond,
T aEpsilon = std::numeric_limits<T>::epsilon() )
278 const T diff =
std::abs( aFirst - aSecond );
280 if( diff < aEpsilon )
287 T largest = aFirst > aSecond ? aFirst : aSecond;
289 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.